about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgaurikholkar <f2013002@goa.bits-pilani.ac.in>2017-04-14 21:04:37 -0700
committergaurikholkar <f2013002@goa.bits-pilani.ac.in>2017-04-28 01:31:42 -0700
commit5436f859e46de9057260269049865b6cdb1d9ddd (patch)
tree2128218b5a8833c2514efcf919d189bd0257d575
parentace517da0d1e356aa5b42f4cdee6854538591ef2 (diff)
downloadrust-5436f859e46de9057260269049865b6cdb1d9ddd.tar.gz
rust-5436f859e46de9057260269049865b6cdb1d9ddd.zip
Disable ref hint for pattern in let and adding ui-tests.
-rw-r--r--src/librustc/hir/map/mod.rs10
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs53
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/move_error.rs34
-rw-r--r--src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs3
-rw-r--r--src/test/ui/issue-40402-ref-hints/issue-40402-1.rs19
-rw-r--r--src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr8
-rw-r--r--src/test/ui/issue-40402-ref-hints/issue-40402-2.rs14
-rw-r--r--src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr11
8 files changed, 132 insertions, 20 deletions
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 48b8a819fff..1948dd909f4 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -95,6 +95,14 @@ enum MapEntry<'hir> {
     RootCrate,
 }
 
+/// Represents the kind of pattern
+#[derive(Debug, Clone, Copy)]
+pub enum PatternSource<'hir> {
+    MatchExpr(&'hir Expr),
+    LetDecl(&'hir Local),
+    Other,
+}
+
 impl<'hir> Clone for MapEntry<'hir> {
     fn clone(&self) -> MapEntry<'hir> {
         *self
@@ -637,7 +645,7 @@ impl<'hir> Map<'hir> {
             Err(id) => id,
         }
     }
-
+    
     /// Returns the nearest enclosing scope. A scope is an item or block.
     /// FIXME it is not clear to me that all items qualify as scopes - statics
     /// and associated types probably shouldn't, for example. Behaviour in this
diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
index 0577ba7f45a..18c9858e8d6 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
@@ -23,13 +23,47 @@ use rustc::ty::{self, Ty};
 use std::rc::Rc;
 use syntax::ast;
 use syntax_pos::Span;
-use rustc::hir::{self, PatKind};
+use rustc::hir::*;
+use rustc::hir::map::Node::*;
+use rustc::hir::map::{PatternSource};
 
 struct GatherMoveInfo<'tcx> {
     id: ast::NodeId,
     kind: MoveKind,
     cmt: mc::cmt<'tcx>,
-    span_path_opt: Option<MoveSpanAndPath>
+    span_path_opt: Option<MoveSpanAndPath<'tcx>>
+}
+
+/// Returns the kind of the Pattern
+fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> PatternSource<'tcx> {
+
+    let parent = tcx.hir.get_parent_node(pat.id);
+
+    match tcx.hir.get(parent) {
+        NodeExpr(ref e) => {
+            // the enclosing expression must be a `match` or something else
+            assert!(match e.node {
+                        ExprMatch(..) => true,
+                        _ => return PatternSource::Other,
+                    });
+            PatternSource::MatchExpr(e)
+        }
+        NodeStmt(ref s) => {
+            // the enclosing statement must be a `let` or something else
+            match s.node {
+                StmtDecl(ref decl, _) => {
+                    match decl.node {
+                        DeclLocal(ref local) => PatternSource::LetDecl(local),
+                        _ => return PatternSource::Other,
+                    }
+                }
+                _ => return PatternSource::Other,
+            }
+        }
+
+        _ => return PatternSource::Other,
+
+    }
 }
 
 pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
@@ -95,11 +129,15 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                       move_error_collector: &mut MoveErrorCollector<'tcx>,
                                       move_pat: &hir::Pat,
                                       cmt: mc::cmt<'tcx>) {
+    let source = get_pattern_source(bccx.tcx,move_pat);
     let pat_span_path_opt = match move_pat.node {
         PatKind::Binding(_, _, ref path1, _) => {
-            Some(MoveSpanAndPath{span: move_pat.span,
-                                 name: path1.node})
-        },
+            Some(MoveSpanAndPath {
+                     span: move_pat.span,
+                     name: path1.node,
+                     pat_source: source,
+                 })
+        }
         _ => None,
     };
     let move_info = GatherMoveInfo {
@@ -108,6 +146,11 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         cmt: cmt,
         span_path_opt: pat_span_path_opt,
     };
+
+    debug!("gather_move_from_pat: move_pat={:?} source={:?}",
+           move_pat,
+           source);
+
     gather_move(bccx, move_data, move_error_collector, move_info);
 }
 
diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
index ebe2de58409..f047374cab2 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
@@ -17,6 +17,7 @@ use rustc::ty;
 use syntax::ast;
 use syntax_pos;
 use errors::DiagnosticBuilder;
+use rustc::hir::map::PatternSource;
 
 pub struct MoveErrorCollector<'tcx> {
     errors: Vec<MoveError<'tcx>>
@@ -40,12 +41,12 @@ impl<'tcx> MoveErrorCollector<'tcx> {
 
 pub struct MoveError<'tcx> {
     move_from: mc::cmt<'tcx>,
-    move_to: Option<MoveSpanAndPath>
+    move_to: Option<MoveSpanAndPath<'tcx>>
 }
 
 impl<'tcx> MoveError<'tcx> {
     pub fn with_move_info(move_from: mc::cmt<'tcx>,
-                          move_to: Option<MoveSpanAndPath>)
+                          move_to: Option<MoveSpanAndPath<'tcx>>)
                           -> MoveError<'tcx> {
         MoveError {
             move_from: move_from,
@@ -55,32 +56,43 @@ impl<'tcx> MoveError<'tcx> {
 }
 
 #[derive(Clone)]
-pub struct MoveSpanAndPath {
+pub struct MoveSpanAndPath<'tcx> {
     pub span: syntax_pos::Span,
     pub name: ast::Name,
+    pub pat_source: PatternSource<'tcx>,
 }
 
 pub struct GroupedMoveErrors<'tcx> {
     move_from: mc::cmt<'tcx>,
-    move_to_places: Vec<MoveSpanAndPath>
+    move_to_places: Vec<MoveSpanAndPath<'tcx>>
 }
 
-fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
-                                errors: &Vec<MoveError<'tcx>>) {
+fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<MoveError<'tcx>>) {
     let grouped_errors = group_errors_with_same_origin(errors);
     for error in &grouped_errors {
         let mut err = report_cannot_move_out_of(bccx, error.move_from.clone());
         let mut is_first_note = true;
-        for move_to in &error.move_to_places {
-            err = note_move_destination(err, move_to.span, move_to.name, is_first_note);
-            is_first_note = false;
+	
+	if let Some(pattern_source) = error.move_to_places.get(0){
+ 
+        match pattern_source.pat_source {
+            PatternSource::LetDecl(_) => {}
+            _ => {
+                for move_to in &error.move_to_places {
+
+                    err = note_move_destination(err, move_to.span, move_to.name, is_first_note);
+                    is_first_note = false;
+                }
+            }
         }
+    }
         if let NoteClosureEnv(upvar_id) = error.move_from.note {
-            err.span_label(bccx.tcx.hir.span(upvar_id.var_id), &"captured outer variable");
+            err.span_label(bccx.tcx.hir.span(upvar_id.var_id), &"captured   outer variable");
         }
         err.emit();
+	
+	}
     }
-}
 
 fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>)
                                        -> Vec<GroupedMoveErrors<'tcx>> {
diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs
index d26364efdbc..98bb6b14b94 100644
--- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs
+++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs
@@ -54,7 +54,6 @@ fn c() {
         _ => {}
     }
     let a = vec[0]; //~ ERROR cannot move out
-    //~^ NOTE to prevent move
     //~| cannot move out of here
 }
 
@@ -68,7 +67,6 @@ fn d() {
         _ => {}
     }
     let a = vec[0]; //~ ERROR cannot move out
-    //~^ NOTE to prevent move
     //~| cannot move out of here
 }
 
@@ -84,7 +82,6 @@ fn e() {
         _ => {}
     }
     let a = vec[0]; //~ ERROR cannot move out
-    //~^ NOTE to prevent move
     //~| cannot move out of here
 }
 
diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-1.rs b/src/test/ui/issue-40402-ref-hints/issue-40402-1.rs
new file mode 100644
index 00000000000..fd42abc752e
--- /dev/null
+++ b/src/test/ui/issue-40402-ref-hints/issue-40402-1.rs
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+struct Foo {
+    pub v: Vec<String>,
+}
+
+fn main() {
+    let mut f = Foo { v: Vec::new() };
+    f.v.push("hello".to_string());
+    let e = f.v[0];
+}
diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr
new file mode 100644
index 00000000000..03b5beee2a4
--- /dev/null
+++ b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr
@@ -0,0 +1,8 @@
+error[E0507]: cannot move out of indexed content
+  --> $DIR/issue-40402-1.rs:18:13
+   |
+18 |     let e = f.v[0];
+   |             ^^^^^^ cannot move out of indexed content
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-2.rs b/src/test/ui/issue-40402-ref-hints/issue-40402-2.rs
new file mode 100644
index 00000000000..0879614243f
--- /dev/null
+++ b/src/test/ui/issue-40402-ref-hints/issue-40402-2.rs
@@ -0,0 +1,14 @@
+// Copyright 2016 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.
+
+fn main() {
+    let x = vec![(String::new(), String::new())];
+    let (a, b) = x[0];
+}
diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr
new file mode 100644
index 00000000000..ab725900015
--- /dev/null
+++ b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr
@@ -0,0 +1,11 @@
+error[E0507]: cannot move out of indexed content
+  --> $DIR/issue-40402-2.rs:13:18
+   |
+13 |     let (a, b) = x[0];
+   |          -  -    ^^^^ cannot move out of indexed content
+   |          |  |
+   |          |  ...and here (use `ref b` or `ref mut b`)
+   |          hint: to prevent move, use `ref a` or `ref mut a`
+
+error: aborting due to previous error
+