about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-10-27 14:25:57 +0000
committerbors <bors@rust-lang.org>2015-10-27 14:25:57 +0000
commit679b5a9faaed845bf4a4bd8fe27a2a98df78b7ad (patch)
tree27eb4af7bc55419ba66729cc3fbeeb0b6be7b666 /src
parenteab5ad529bf1d0406b25c52cc1b5281bc54c5679 (diff)
parent4e2189fe457e246654f6da6152da1609b392aeea (diff)
downloadrust-679b5a9faaed845bf4a4bd8fe27a2a98df78b7ad.tar.gz
rust-679b5a9faaed845bf4a4bd8fe27a2a98df78b7ad.zip
Auto merge of #29327 - sanxiyn:argument, r=nrc
Fix #24114.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/front/map/collector.rs17
-rw-r--r--src/librustc/front/map/mod.rs32
-rw-r--r--src/librustc/middle/expr_use_visitor.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs11
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs2
-rw-r--r--src/librustc_trans/trans/monomorphize.rs1
-rw-r--r--src/test/compile-fail/borrowck-argument.rs43
-rw-r--r--src/test/compile-fail/borrowck-closures-unique.rs2
-rw-r--r--src/test/compile-fail/borrowck-unboxed-closures.rs2
9 files changed, 74 insertions, 38 deletions
diff --git a/src/librustc/front/map/collector.rs b/src/librustc/front/map/collector.rs
index 458e423b826..f255949a9f5 100644
--- a/src/librustc/front/map/collector.rs
+++ b/src/librustc/front/map/collector.rs
@@ -104,12 +104,6 @@ impl<'ast> NodeCollector<'ast> {
         let entry = MapEntry::from_node(self.parent_node, node);
         self.insert_entry(id, entry);
     }
-
-    fn visit_fn_decl(&mut self, decl: &'ast FnDecl) {
-        for a in &decl.inputs {
-            self.insert(a.id, NodeArg(&*a.pat));
-        }
-    }
 }
 
 impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
@@ -295,20 +289,9 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
     fn visit_fn(&mut self, fk: visit::FnKind<'ast>, fd: &'ast FnDecl,
                 b: &'ast Block, s: Span, id: NodeId) {
         assert_eq!(self.parent_node, id);
-        self.visit_fn_decl(fd);
         visit::walk_fn(self, fk, fd, b, s);
     }
 
-    fn visit_ty(&mut self, ty: &'ast Ty) {
-        match ty.node {
-            TyBareFn(ref fd) => {
-                self.visit_fn_decl(&*fd.decl);
-            }
-            _ => {}
-        }
-        visit::walk_ty(self, ty);
-    }
-
     fn visit_block(&mut self, block: &'ast Block) {
         self.insert(block.id, NodeBlock(block));
         let parent_node = self.parent_node;
diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs
index 2d84f6fc2be..94800db184e 100644
--- a/src/librustc/front/map/mod.rs
+++ b/src/librustc/front/map/mod.rs
@@ -118,7 +118,6 @@ pub enum Node<'ast> {
     NodeVariant(&'ast Variant),
     NodeExpr(&'ast Expr),
     NodeStmt(&'ast Stmt),
-    NodeArg(&'ast Pat),
     NodeLocal(&'ast Pat),
     NodePat(&'ast Pat),
     NodeBlock(&'ast Block),
@@ -145,7 +144,6 @@ pub enum MapEntry<'ast> {
     EntryVariant(NodeId, &'ast Variant),
     EntryExpr(NodeId, &'ast Expr),
     EntryStmt(NodeId, &'ast Stmt),
-    EntryArg(NodeId, &'ast Pat),
     EntryLocal(NodeId, &'ast Pat),
     EntryPat(NodeId, &'ast Pat),
     EntryBlock(NodeId, &'ast Block),
@@ -180,7 +178,6 @@ impl<'ast> MapEntry<'ast> {
             NodeVariant(n) => EntryVariant(p, n),
             NodeExpr(n) => EntryExpr(p, n),
             NodeStmt(n) => EntryStmt(p, n),
-            NodeArg(n) => EntryArg(p, n),
             NodeLocal(n) => EntryLocal(p, n),
             NodePat(n) => EntryPat(p, n),
             NodeBlock(n) => EntryBlock(p, n),
@@ -199,7 +196,6 @@ impl<'ast> MapEntry<'ast> {
             EntryVariant(id, _) => id,
             EntryExpr(id, _) => id,
             EntryStmt(id, _) => id,
-            EntryArg(id, _) => id,
             EntryLocal(id, _) => id,
             EntryPat(id, _) => id,
             EntryBlock(id, _) => id,
@@ -219,7 +215,6 @@ impl<'ast> MapEntry<'ast> {
             EntryVariant(_, n) => NodeVariant(n),
             EntryExpr(_, n) => NodeExpr(n),
             EntryStmt(_, n) => NodeStmt(n),
-            EntryArg(_, n) => NodeArg(n),
             EntryLocal(_, n) => NodeLocal(n),
             EntryPat(_, n) => NodePat(n),
             EntryBlock(_, n) => NodeBlock(n),
@@ -348,6 +343,27 @@ impl<'ast> Map<'ast> {
         self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id)
     }
 
+    /// Check if the node is an argument. An argument is a local variable whose
+    /// immediate parent is an item or a closure.
+    pub fn is_argument(&self, id: NodeId) -> bool {
+        match self.find(id) {
+            Some(NodeLocal(_)) => (),
+            _ => return false,
+        }
+        match self.find(self.get_parent_node(id)) {
+            Some(NodeItem(_)) |
+            Some(NodeTraitItem(_)) |
+            Some(NodeImplItem(_)) => true,
+            Some(NodeExpr(e)) => {
+                match e.node {
+                    ExprClosure(..) => true,
+                    _ => false,
+                }
+            }
+            _ => false,
+        }
+    }
+
     /// If there is some error when walking the parents (e.g., a node does not
     /// have a parent in the map or a node can't be found), then we return the
     /// last good node id we found. Note that reaching the crate root (id == 0),
@@ -628,7 +644,7 @@ impl<'ast> Map<'ast> {
             Some(NodeVariant(variant)) => variant.span,
             Some(NodeExpr(expr)) => expr.span,
             Some(NodeStmt(stmt)) => stmt.span,
-            Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
+            Some(NodeLocal(pat)) => pat.span,
             Some(NodePat(pat)) => pat.span,
             Some(NodeBlock(block)) => block.span,
             Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
@@ -886,7 +902,6 @@ impl<'a> NodePrinter for pprust::State<'a> {
             // ast_map to reconstruct their full structure for pretty
             // printing.
             NodeLocal(_)       => panic!("cannot print isolated Local"),
-            NodeArg(_)         => panic!("cannot print isolated Arg"),
             NodeStructCtor(_)  => panic!("cannot print isolated StructCtor"),
         }
     }
@@ -965,9 +980,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
         Some(NodeStmt(ref stmt)) => {
             format!("stmt {}{}", pprust::stmt_to_string(&**stmt), id_str)
         }
-        Some(NodeArg(ref pat)) => {
-            format!("arg {}{}", pprust::pat_to_string(&**pat), id_str)
-        }
         Some(NodeLocal(ref pat)) => {
             format!("local {}{}", pprust::pat_to_string(&**pat), id_str)
         }
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index e1f8aaead88..fb3a6b0f420 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -278,7 +278,7 @@ enum PassArgs {
 impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
     pub fn new(delegate: &'d mut (Delegate<'tcx>),
                typer: &'t infer::InferCtxt<'a, 'tcx>)
-               -> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a
+               -> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a+'d
     {
         let mc: mc::MemCategorizationContext<'t, 'a, 'tcx> =
             mc::MemCategorizationContext::new(typer);
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 555f864befb..1fcd6e92305 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -305,7 +305,7 @@ impl MutabilityCategory {
 
     fn from_local(tcx: &ty::ctxt, id: ast::NodeId) -> MutabilityCategory {
         let ret = match tcx.map.get(id) {
-            ast_map::NodeLocal(p) | ast_map::NodeArg(p) => match p.node {
+            ast_map::NodeLocal(p) => match p.node {
                 hir::PatIdent(bind_mode, _, _) => {
                     if bind_mode == hir::BindByValue(hir::MutMutable) {
                         McDeclared
@@ -1463,11 +1463,10 @@ impl<'tcx> cmt_<'tcx> {
                 "non-lvalue".to_string()
             }
             cat_local(vid) => {
-                match tcx.map.find(vid) {
-                    Some(ast_map::NodeArg(_)) => {
-                        "argument".to_string()
-                    }
-                    _ => "local variable".to_string()
+                if tcx.map.is_argument(vid) {
+                    "argument".to_string()
+                } else {
+                    "local variable".to_string()
                 }
             }
             cat_deref(_, _, pk) => {
diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs
index 62befb3b992..2e7b1f31ba9 100644
--- a/src/librustc_trans/trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/trans/debuginfo/metadata.rs
@@ -1976,7 +1976,7 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         None => {
             cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
         }
-        Some(hir_map::NodeLocal(pat)) | Some(hir_map::NodeArg(pat)) => {
+        Some(hir_map::NodeLocal(pat)) => {
             match pat.node {
                 hir::PatIdent(_, ref path1, _) => {
                     path1.node.name
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index f84f0feb960..1f9116f7491 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -262,7 +262,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         hir_map::NodeTyParam(..) |
         hir_map::NodeExpr(..) |
         hir_map::NodeStmt(..) |
-        hir_map::NodeArg(..) |
         hir_map::NodeBlock(..) |
         hir_map::NodePat(..) |
         hir_map::NodeLocal(..) => {
diff --git a/src/test/compile-fail/borrowck-argument.rs b/src/test/compile-fail/borrowck-argument.rs
new file mode 100644
index 00000000000..3230689e53c
--- /dev/null
+++ b/src/test/compile-fail/borrowck-argument.rs
@@ -0,0 +1,43 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[derive(Copy, Clone)]
+struct S;
+
+impl S {
+    fn mutate(&mut self) {
+    }
+}
+
+fn func(arg: S) {
+    arg.mutate(); //~ ERROR: cannot borrow immutable argument
+}
+
+impl S {
+    fn method(&self, arg: S) {
+        arg.mutate(); //~ ERROR: cannot borrow immutable argument
+    }
+}
+
+trait T {
+    fn default(&self, arg: S) {
+        arg.mutate(); //~ ERROR: cannot borrow immutable argument
+    }
+}
+
+impl T for S {}
+
+fn main() {
+    let s = S;
+    func(s);
+    s.method(s);
+    s.default(s);
+    (|arg: S| { arg.mutate() })(s); //~ ERROR: cannot borrow immutable argument
+}
diff --git a/src/test/compile-fail/borrowck-closures-unique.rs b/src/test/compile-fail/borrowck-closures-unique.rs
index 9410181659c..3646a68f06f 100644
--- a/src/test/compile-fail/borrowck-closures-unique.rs
+++ b/src/test/compile-fail/borrowck-closures-unique.rs
@@ -43,7 +43,7 @@ fn d(x: &mut isize) {
 }
 
 fn e(x: &mut isize) {
-    let c1 = || x = panic!(); //~ ERROR closure cannot assign to immutable local variable
+    let c1 = || x = panic!(); //~ ERROR closure cannot assign to immutable argument
 }
 
 fn main() {
diff --git a/src/test/compile-fail/borrowck-unboxed-closures.rs b/src/test/compile-fail/borrowck-unboxed-closures.rs
index 3eca850e493..1c12ca9c1de 100644
--- a/src/test/compile-fail/borrowck-unboxed-closures.rs
+++ b/src/test/compile-fail/borrowck-unboxed-closures.rs
@@ -17,7 +17,7 @@ fn a<F:Fn(isize, isize) -> isize>(mut f: F) {
 }
 
 fn b<F:FnMut(isize, isize) -> isize>(f: F) {
-    f(1, 2);    //~ ERROR cannot borrow immutable local variable
+    f(1, 2);    //~ ERROR cannot borrow immutable argument
 }
 
 fn c<F:FnOnce(isize, isize) -> isize>(f: F) {