use rustc::hir::intravisit as visit;
use rustc::hir::map::Node::{NodeExpr, NodeStmt};
use rustc::lint::*;
+use rustc::{declare_lint, lint_array};
use rustc::middle::expr_use_visitor::*;
-use rustc::middle::mem_categorization::{cmt, Categorization};
+use rustc::middle::mem_categorization::{cmt_, Categorization};
use rustc::ty::{self, Ty};
+use rustc::ty::layout::LayoutOf;
use rustc::util::nodemap::NodeSet;
use syntax::ast::NodeId;
use syntax::codemap::Span;
-use utils::{span_lint, type_size};
+use crate::utils::span_lint;
pub struct Pass {
pub too_large_for_stack: u64,
/// println!("{}", *x);
/// }
/// ```
-declare_lint! {
+declare_clippy_lint! {
pub BOXED_LOCAL,
- Warn,
+ perf,
"using `Box<T>` where unnecessary"
}
) {
let fn_def_id = cx.tcx.hir.local_def_id(node_id);
let mut v = EscapeDelegate {
- cx: cx,
+ cx,
set: NodeSet(),
too_large_for_stack: self.too_large_for_stack,
};
}
impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
- fn consume(&mut self, _: NodeId, _: Span, cmt: cmt<'tcx>, mode: ConsumeMode) {
+ fn consume(&mut self, _: NodeId, _: Span, cmt: &cmt_<'tcx>, mode: ConsumeMode) {
if let Categorization::Local(lid) = cmt.cat {
if let Move(DirectRefMove) = mode {
// moved out or in. clearly can't be localized
}
}
}
- fn matched_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: MatchMode) {}
- fn consume_pat(&mut self, consume_pat: &Pat, cmt: cmt<'tcx>, _: ConsumeMode) {
+ fn matched_pat(&mut self, _: &Pat, _: &cmt_<'tcx>, _: MatchMode) {}
+ fn consume_pat(&mut self, consume_pat: &Pat, cmt: &cmt_<'tcx>, _: ConsumeMode) {
let map = &self.cx.tcx.hir;
if map.is_argument(consume_pat.id) {
// Skip closure arguments
return;
}
if let Categorization::Rvalue(..) = cmt.cat {
- if let Some(NodeStmt(st)) = map.find(map.get_parent_node(cmt.id)) {
- if let StmtDecl(ref decl, _) = st.node {
- if let DeclLocal(ref loc) = decl.node {
+ let id = map.hir_to_node_id(cmt.hir_id);
+ if let Some(NodeStmt(st)) = map.find(map.get_parent_node(id)) {
+ if let StmtKind::Decl(ref decl, _) = st.node {
+ if let DeclKind::Local(ref loc) = decl.node {
if let Some(ref ex) = loc.init {
- if let ExprBox(..) = ex.node {
+ if let ExprKind::Box(..) = ex.node {
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
// let x = box (...)
self.set.insert(consume_pat.id);
}
}
}
- fn borrow(&mut self, _: NodeId, _: Span, cmt: cmt<'tcx>, _: ty::Region, _: ty::BorrowKind, loan_cause: LoanCause) {
+ fn borrow(&mut self, _: NodeId, _: Span, cmt: &cmt_<'tcx>, _: ty::Region, _: ty::BorrowKind, loan_cause: LoanCause) {
if let Categorization::Local(lid) = cmt.cat {
match loan_cause {
// x.foo()
}
}
fn decl_without_init(&mut self, _: NodeId, _: Span) {}
- fn mutate(&mut self, _: NodeId, _: Span, _: cmt<'tcx>, _: MutateMode) {}
+ fn mutate(&mut self, _: NodeId, _: Span, _: &cmt_<'tcx>, _: MutateMode) {}
}
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
// Large types need to be boxed to avoid stack
// overflows.
if ty.is_box() {
- type_size(self.cx, ty.boxed_ty()).unwrap_or(0) > self.too_large_for_stack
+ self.cx.layout_of(ty.boxed_ty()).ok().map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
} else {
false
}