]> git.lizzy.rs Git - rust.git/blobdiff - src/escape.rs
Rustup to 1.9.0-nightly (5ab11d72c 2016-04-02)
[rust.git] / src / escape.rs
index edc7b5c6fbbddf284bf0a52546de8ce54d41cf4e..98500bf62f016ba78178409d95c69eeada040c18 100644 (file)
@@ -1,20 +1,21 @@
-use rustc::lint::*;
 use rustc::front::map::Node::{NodeExpr, NodeStmt};
-use rustc_front::hir::*;
-use rustc_front::intravisit as visit;
-use rustc::middle::ty;
-use rustc::middle::ty::adjustment::AutoAdjustment;
+use rustc::lint::*;
 use rustc::middle::expr_use_visitor::*;
-use rustc::middle::infer;
+use rustc::infer;
 use rustc::middle::mem_categorization::{cmt, Categorization};
+use rustc::traits::ProjectionMode;
+use rustc::ty::adjustment::AutoAdjustment;
+use rustc::ty;
 use rustc::util::nodemap::NodeSet;
+use rustc_front::hir::*;
+use rustc_front::intravisit as visit;
 use syntax::ast::NodeId;
 use syntax::codemap::Span;
 use utils::span_lint;
 
 pub struct EscapePass;
 
-/// **What it does:** This lint checks for usage of `Box<T>` where an unboxed `T` would work fine. It is `Warn` by default.
+/// **What it does:** This lint checks for usage of `Box<T>` where an unboxed `T` would work fine.
 ///
 /// **Why is this bad?** This is an unnecessary allocation, and bad for performance. It is only necessary to allocate if you wish to move the box into something.
 ///
 ///     println!("{}", *x);
 /// }
 /// ```
-declare_lint!(pub BOXED_LOCAL, Warn, "using Box<T> where unnecessary");
+declare_lint! {
+    pub BOXED_LOCAL, Warn, "using Box<T> where unnecessary"
+}
 
-fn is_box(ty: ty::Ty) -> bool {
+fn is_non_trait_box(ty: ty::Ty) -> bool {
     match ty.sty {
-        ty::TyBox(..) => true,
-        _ => false
+        ty::TyBox(ref inner) => !inner.is_trait(),
+        _ => false,
     }
 }
 
@@ -52,7 +55,7 @@ fn get_lints(&self) -> LintArray {
 impl LateLintPass for EscapePass {
     fn check_fn(&mut self, cx: &LateContext, _: visit::FnKind, decl: &FnDecl, body: &Block, _: Span, id: NodeId) {
         let param_env = ty::ParameterEnvironment::for_item(cx.tcx, id);
-        let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(param_env));
+        let infcx = infer::new_infer_ctxt(cx.tcx, &cx.tcx.tables, Some(param_env), ProjectionMode::Any);
         let mut v = EscapeDelegate {
             cx: cx,
             set: NodeSet(),
@@ -90,7 +93,7 @@ fn consume_pat(&mut self, consume_pat: &Pat, cmt: cmt<'tcx>, _: ConsumeMode) {
             if let Some(NodeExpr(..)) = map.find(map.get_parent_node(consume_pat.id)) {
                 return;
             }
-            if is_box(cmt.ty) {
+            if is_non_trait_box(cmt.ty) {
                 self.set.insert(consume_pat.id);
             }
             return;
@@ -101,7 +104,7 @@ fn consume_pat(&mut self, consume_pat: &Pat, cmt: cmt<'tcx>, _: ConsumeMode) {
                     if let DeclLocal(ref loc) = decl.node {
                         if let Some(ref ex) = loc.init {
                             if let ExprBox(..) = ex.node {
-                                if is_box(cmt.ty) {
+                                if is_non_trait_box(cmt.ty) {
                                     // let x = box (...)
                                     self.set.insert(consume_pat.id);
                                 }
@@ -137,11 +140,11 @@ fn borrow(&mut self, borrow_id: NodeId, _: Span, cmt: cmt<'tcx>, _: ty::Region,
                                                                         .get(&borrow_id) {
                     if LoanCause::AutoRef == loan_cause {
                         // x.foo()
-                        if adj.autoderefs <= 0 {
+                        if adj.autoderefs == 0 {
                             self.set.remove(&lid); // Used without autodereffing (i.e. x.clone())
                         }
                     } else {
-                        self.cx.sess().span_bug(cmt.span, "Unknown adjusted AutoRef");
+                        span_bug!(cmt.span, "Unknown adjusted AutoRef");
                     }
                 } else if LoanCause::AddrOf == loan_cause {
                     // &x