]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/mem_categorization.rs
rollup merge of #17355 : gamazeps/issue17210
[rust.git] / src / librustc / middle / mem_categorization.rs
index abed04c8f33acf7cf90f98d4dc151af9521822b2..6350fa6a5068713dbb52c748b40caeba8738456a 100644 (file)
@@ -63,7 +63,6 @@
 #![allow(non_camel_case_types)]
 
 use middle::def;
-use middle::freevars;
 use middle::ty;
 use middle::typeck;
 use util::nodemap::{DefIdMap, NodeMap};
@@ -71,6 +70,7 @@
 
 use syntax::ast::{MutImmutable, MutMutable};
 use syntax::ast;
+use syntax::ast_map;
 use syntax::codemap::Span;
 use syntax::print::pprust;
 use syntax::parse::token;
@@ -85,7 +85,6 @@ pub enum categorization {
     cat_copied_upvar(CopiedUpvar),     // upvar copied into proc env
     cat_upvar(ty::UpvarId, ty::UpvarBorrow), // by ref upvar from stack closure
     cat_local(ast::NodeId),            // local variable
-    cat_arg(ast::NodeId),              // formal argument
     cat_deref(cmt, uint, PointerKind), // deref of a ptr
     cat_interior(cmt, InteriorKind),   // something interior: field, tuple, etc
     cat_downcast(cmt),                 // selects a particular enum variant (*1)
@@ -273,7 +272,7 @@ pub trait Typer<'tcx> {
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<ast::NodeId>;
     fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
     fn capture_mode(&self, closure_expr_id: ast::NodeId)
-                    -> freevars::CaptureMode;
+                    -> ast::CaptureClause;
     fn unboxed_closures<'a>(&'a self)
                         -> &'a RefCell<DefIdMap<ty::UnboxedClosure>>;
 }
@@ -312,26 +311,19 @@ pub fn from_pointer_kind(base_mutbl: MutabilityCategory,
         }
     }
 
-    fn from_def(def: &def::Def) -> MutabilityCategory {
-        match *def {
-            def::DefFn(..) | def::DefStaticMethod(..) | def::DefSelfTy(..) |
-            def::DefMod(..) | def::DefForeignMod(..) | def::DefVariant(..) |
-            def::DefTy(..) | def::DefTrait(..) | def::DefPrimTy(..) |
-            def::DefTyParam(..) | def::DefUse(..) | def::DefStruct(..) |
-            def::DefTyParamBinder(..) | def::DefRegion(..) | def::DefLabel(..) |
-            def::DefMethod(..) => fail!("no MutabilityCategory for def: {}", *def),
-
-            def::DefStatic(_, false) => McImmutable,
-            def::DefStatic(_, true) => McDeclared,
-
-            def::DefArg(_, binding_mode) |
-            def::DefBinding(_, binding_mode) |
-            def::DefLocal(_, binding_mode)  => match binding_mode {
-                ast::BindByValue(ast::MutMutable) => McDeclared,
-                _ => McImmutable
+    fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory {
+        match tcx.map.get(id) {
+            ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node {
+                ast::PatIdent(bind_mode, _, _) => {
+                    if bind_mode == ast::BindByValue(ast::MutMutable) {
+                        McDeclared
+                    } else {
+                        McImmutable
+                    }
+                }
+                _ => tcx.sess.span_bug(p.span, "expected identifier pattern")
             },
-
-            def::DefUpvar(_, def, _, _) => MutabilityCategory::from_def(&*def)
+            _ => tcx.sess.span_bug(tcx.map.span(id), "expected identifier pattern")
         }
     }
 
@@ -412,14 +404,14 @@ pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt> {
 
             Some(adjustment) => {
                 match *adjustment {
-                    ty::AutoAddEnv(..) => {
+                    ty::AdjustAddEnv(..) => {
                         // Convert a bare fn to a closure by adding NULL env.
                         // Result is an rvalue.
                         let expr_ty = if_ok!(self.expr_ty_adjusted(expr));
                         Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
                     }
 
-                    ty::AutoDerefRef(
+                    ty::AdjustDerefRef(
                         ty::AutoDerefRef {
                             autoref: Some(_), ..}) => {
                         // Equivalent to &*expr or something similar.
@@ -428,7 +420,7 @@ pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt> {
                         Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty))
                     }
 
-                    ty::AutoDerefRef(
+                    ty::AdjustDerefRef(
                         ty::AutoDerefRef {
                             autoref: None, autoderefs: autoderefs}) => {
                         // Equivalent to *expr or something similar.
@@ -465,6 +457,11 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt> {
             Ok(self.cat_field(expr, base_cmt, f_name.node, expr_ty))
           }
 
+          ast::ExprTupField(ref base, idx, _) => {
+            let base_cmt = if_ok!(self.cat_expr(&**base));
+            Ok(self.cat_tup_field(expr, base_cmt, idx.node, expr_ty))
+          }
+
           ast::ExprIndex(ref base, _) => {
             let method_call = typeck::MethodCall::expr(expr.id());
             match self.typer.node_method_ty(method_call) {
@@ -485,7 +482,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt> {
           }
 
           ast::ExprPath(_) => {
-            let def = self.tcx().def_map.borrow().get_copy(&expr.id);
+            let def = *self.tcx().def_map.borrow().get(&expr.id);
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
@@ -497,7 +494,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt> {
           ast::ExprAssign(..) | ast::ExprAssignOp(..) |
           ast::ExprFnBlock(..) | ast::ExprProc(..) |
           ast::ExprUnboxedFn(..) | ast::ExprRet(..) |
-          ast::ExprUnary(..) |
+          ast::ExprUnary(..) | ast::ExprSlice(..) |
           ast::ExprMethodCall(..) | ast::ExprCast(..) |
           ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
           ast::ExprBinary(..) | ast::ExprWhile(..) |
@@ -526,9 +523,10 @@ pub fn cat_def(&self,
                 Ok(self.cat_rvalue_node(id, span, expr_ty))
           }
           def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
-          def::DefTrait(_) | def::DefTy(_) | def::DefPrimTy(_) |
+          def::DefTrait(_) | def::DefTy(..) | def::DefPrimTy(_) |
           def::DefTyParam(..) | def::DefTyParamBinder(..) | def::DefRegion(_) |
-          def::DefLabel(_) | def::DefSelfTy(..) | def::DefMethod(..) => {
+          def::DefLabel(_) | def::DefSelfTy(..) | def::DefMethod(..) |
+          def::DefAssociatedTy(..) => {
               Ok(Rc::new(cmt_ {
                   id:id,
                   span:span,
@@ -538,30 +536,17 @@ pub fn cat_def(&self,
               }))
           }
 
-          def::DefStatic(_, _) => {
+          def::DefStatic(_, mutbl) => {
               Ok(Rc::new(cmt_ {
                   id:id,
                   span:span,
                   cat:cat_static_item,
-                  mutbl: MutabilityCategory::from_def(&def),
+                  mutbl: if mutbl { McDeclared } else { McImmutable},
                   ty:expr_ty
               }))
           }
 
-          def::DefArg(vid, _) => {
-            // Idea: make this could be rewritten to model by-ref
-            // stuff as `&const` and `&mut`?
-
-            Ok(Rc::new(cmt_ {
-                id: id,
-                span: span,
-                cat: cat_arg(vid),
-                mutbl: MutabilityCategory::from_def(&def),
-                ty:expr_ty
-            }))
-          }
-
-          def::DefUpvar(var_id, _, fn_node_id, _) => {
+          def::DefUpvar(var_id, fn_node_id, _) => {
               let ty = if_ok!(self.node_ty(fn_node_id));
               match ty::get(ty).sty {
                   ty::ty_closure(ref closure_ty) => {
@@ -589,7 +574,7 @@ pub fn cat_def(&self,
                                   onceness: closure_ty.onceness,
                                   capturing_proc: fn_node_id,
                               }),
-                              mutbl: MutabilityCategory::from_def(&def),
+                              mutbl: MutabilityCategory::from_local(self.tcx(), var_id),
                               ty:expr_ty
                           }))
                       }
@@ -612,7 +597,7 @@ pub fn cat_def(&self,
                               onceness: onceness,
                               capturing_proc: fn_node_id,
                           }),
-                          mutbl: MutabilityCategory::from_def(&def),
+                          mutbl: MutabilityCategory::from_local(self.tcx(), var_id),
                           ty: expr_ty
                       }))
                   }
@@ -626,14 +611,12 @@ pub fn cat_def(&self,
               }
           }
 
-          def::DefLocal(vid, _) |
-          def::DefBinding(vid, _) => {
-            // by-value/by-ref bindings are local variables
+          def::DefLocal(vid) => {
             Ok(Rc::new(cmt_ {
                 id: id,
                 span: span,
                 cat: cat_local(vid),
-                mutbl: MutabilityCategory::from_def(&def),
+                mutbl: MutabilityCategory::from_local(self.tcx(), vid),
                 ty: expr_ty
             }))
           }
@@ -737,6 +720,21 @@ pub fn cat_field<N:ast_node>(&self,
         })
     }
 
+    pub fn cat_tup_field<N:ast_node>(&self,
+                                     node: &N,
+                                     base_cmt: cmt,
+                                     f_idx: uint,
+                                     f_ty: ty::t)
+                                     -> cmt {
+        Rc::new(cmt_ {
+            id: node.id(),
+            span: node.span(),
+            mutbl: base_cmt.mutbl.inherit(),
+            cat: cat_interior(base_cmt, InteriorField(PositionalField(f_idx))),
+            ty: f_ty
+        })
+    }
+
     pub fn cat_deref_obj<N:ast_node>(&self, node: &N, base_cmt: cmt) -> cmt {
         self.cat_deref_common(node, base_cmt, 0, ty::mk_nil(), false)
     }
@@ -1134,7 +1132,7 @@ pub fn cat_pattern(&self,
             if_ok!(self.cat_pattern(subcmt, &**subpat, op));
           }
 
-          ast::PatVec(ref before, slice, ref after) => {
+          ast::PatVec(ref before, ref slice, ref after) => {
               let elt_cmt = self.cat_index(pat, self.deref_vec(pat, cmt));
               for before_pat in before.iter() {
                   if_ok!(self.cat_pattern(elt_cmt.clone(), &**before_pat,
@@ -1173,11 +1171,13 @@ pub fn cmt_to_string(&self, cmt: &cmt_) -> String {
           cat_rvalue(..) => {
               "non-lvalue".to_string()
           }
-          cat_local(_) => {
-              "local variable".to_string()
-          }
-          cat_arg(..) => {
-              "argument".to_string()
+          cat_local(vid) => {
+              match self.tcx().map.find(vid) {
+                  Some(ast_map::NodeArg(_)) => {
+                      "argument".to_string()
+                  }
+                  _ => "local variable".to_string()
+              }
           }
           cat_deref(ref base, _, pk) => {
               match base.cat {
@@ -1244,7 +1244,6 @@ pub fn guarantor(&self) -> cmt {
             cat_static_item |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_arg(..) |
             cat_deref(_, _, UnsafePtr(..)) |
             cat_deref(_, _, GcPtr(..)) |
             cat_deref(_, _, BorrowedPtr(..)) |
@@ -1288,7 +1287,6 @@ pub fn freely_aliasable(&self, ctxt: &ty::ctxt) -> Option<AliasableReason> {
             cat_rvalue(..) |
             cat_local(..) |
             cat_upvar(..) |
-            cat_arg(_) |
             cat_deref(_, _, UnsafePtr(..)) => { // yes, it's aliasable, but...
                 None
             }
@@ -1340,8 +1338,7 @@ fn repr(&self, tcx: &ty::ctxt) -> String {
             cat_rvalue(..) |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_upvar(..) |
-            cat_arg(..) => {
+            cat_upvar(..) => {
                 format!("{:?}", *self)
             }
             cat_deref(ref cmt, derefs, ptr) => {