Skip to content

Commit 0680769

Browse files
committed
Disable ref hint for pattern in let and adding ui-tests.
1 parent 0369832 commit 0680769

File tree

8 files changed

+131
-20
lines changed

8 files changed

+131
-20
lines changed

src/librustc/hir/map/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ enum MapEntry<'hir> {
9595
RootCrate,
9696
}
9797

98+
/// Represents the kind of pattern
99+
#[derive(Debug, Clone, Copy)]
100+
pub enum PatternSource<'hir> {
101+
MatchExpr(&'hir Expr),
102+
LetDecl(&'hir Local),
103+
Other,
104+
}
105+
98106
impl<'hir> Clone for MapEntry<'hir> {
99107
fn clone(&self) -> MapEntry<'hir> {
100108
*self
@@ -637,7 +645,7 @@ impl<'hir> Map<'hir> {
637645
Err(id) => id,
638646
}
639647
}
640-
648+
641649
/// Returns the nearest enclosing scope. A scope is an item or block.
642650
/// FIXME it is not clear to me that all items qualify as scopes - statics
643651
/// and associated types probably shouldn't, for example. Behaviour in this

src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs

+48-5
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,47 @@ use rustc::ty::{self, Ty};
2323
use std::rc::Rc;
2424
use syntax::ast;
2525
use syntax_pos::Span;
26-
use rustc::hir::{self, PatKind};
26+
use rustc::hir::*;
27+
use rustc::hir::map::Node::*;
28+
use rustc::hir::map::{PatternSource};
2729

2830
struct GatherMoveInfo<'tcx> {
2931
id: ast::NodeId,
3032
kind: MoveKind,
3133
cmt: mc::cmt<'tcx>,
32-
span_path_opt: Option<MoveSpanAndPath>
34+
span_path_opt: Option<MoveSpanAndPath<'tcx>>
35+
}
36+
37+
/// Returns the kind of the Pattern
38+
fn get_pattern_source<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &Pat) -> PatternSource<'tcx> {
39+
40+
let parent = tcx.hir.get_parent_node(pat.id);
41+
42+
match tcx.hir.get(parent) {
43+
NodeExpr(ref e) => {
44+
// the enclosing expression must be a `match` or something else
45+
assert!(match e.node {
46+
ExprMatch(..) => true,
47+
_ => return PatternSource::Other,
48+
});
49+
PatternSource::MatchExpr(e)
50+
}
51+
NodeStmt(ref s) => {
52+
// the enclosing statement must be a `let` or something else
53+
match s.node {
54+
StmtDecl(ref decl, _) => {
55+
match decl.node {
56+
DeclLocal(ref local) => PatternSource::LetDecl(local),
57+
_ => return PatternSource::Other,
58+
}
59+
}
60+
_ => return PatternSource::Other,
61+
}
62+
}
63+
64+
_ => return PatternSource::Other,
65+
66+
}
3367
}
3468

3569
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>,
95129
move_error_collector: &mut MoveErrorCollector<'tcx>,
96130
move_pat: &hir::Pat,
97131
cmt: mc::cmt<'tcx>) {
132+
let source = get_pattern_source(bccx.tcx,move_pat);
98133
let pat_span_path_opt = match move_pat.node {
99134
PatKind::Binding(_, _, ref path1, _) => {
100-
Some(MoveSpanAndPath{span: move_pat.span,
101-
name: path1.node})
102-
},
135+
Some(MoveSpanAndPath {
136+
span: move_pat.span,
137+
name: path1.node,
138+
pat_source: source,
139+
})
140+
}
103141
_ => None,
104142
};
105143
let move_info = GatherMoveInfo {
@@ -108,6 +146,11 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
108146
cmt: cmt,
109147
span_path_opt: pat_span_path_opt,
110148
};
149+
150+
debug!("gather_move_from_pat: move_pat={:?} source={:?}",
151+
move_pat,
152+
source);
153+
111154
gather_move(bccx, move_data, move_error_collector, move_info);
112155
}
113156

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc::ty;
1616
use syntax::ast;
1717
use syntax_pos;
1818
use errors::DiagnosticBuilder;
19+
use rustc::hir::map::PatternSource;
1920

2021
pub struct MoveErrorCollector<'tcx> {
2122
errors: Vec<MoveError<'tcx>>
@@ -39,12 +40,12 @@ impl<'tcx> MoveErrorCollector<'tcx> {
3940

4041
pub struct MoveError<'tcx> {
4142
move_from: mc::cmt<'tcx>,
42-
move_to: Option<MoveSpanAndPath>
43+
move_to: Option<MoveSpanAndPath<'tcx>>
4344
}
4445

4546
impl<'tcx> MoveError<'tcx> {
4647
pub fn with_move_info(move_from: mc::cmt<'tcx>,
47-
move_to: Option<MoveSpanAndPath>)
48+
move_to: Option<MoveSpanAndPath<'tcx>>)
4849
-> MoveError<'tcx> {
4950
MoveError {
5051
move_from: move_from,
@@ -54,30 +55,40 @@ impl<'tcx> MoveError<'tcx> {
5455
}
5556

5657
#[derive(Clone)]
57-
pub struct MoveSpanAndPath {
58+
pub struct MoveSpanAndPath<'tcx> {
5859
pub span: syntax_pos::Span,
5960
pub name: ast::Name,
61+
pub pat_source: PatternSource<'tcx>,
6062
}
6163

6264
pub struct GroupedMoveErrors<'tcx> {
6365
move_from: mc::cmt<'tcx>,
64-
move_to_places: Vec<MoveSpanAndPath>
66+
move_to_places: Vec<MoveSpanAndPath<'tcx>>
6567
}
6668

67-
fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
68-
errors: &Vec<MoveError<'tcx>>) {
69+
fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<MoveError<'tcx>>) {
6970
let grouped_errors = group_errors_with_same_origin(errors);
7071
for error in &grouped_errors {
7172
let mut err = report_cannot_move_out_of(bccx, error.move_from.clone());
7273
let mut is_first_note = true;
73-
for move_to in &error.move_to_places {
74-
err = note_move_destination(err, move_to.span,
75-
move_to.name, is_first_note);
76-
is_first_note = false;
74+
75+
if let Some(pattern_source) = error.move_to_places.get(0){
76+
77+
match pattern_source.pat_source {
78+
PatternSource::LetDecl(_) => {}
79+
_ => {
80+
for move_to in &error.move_to_places {
81+
82+
err = note_move_destination(err, move_to.span, move_to.name, is_first_note);
83+
is_first_note = false;
84+
}
85+
}
7786
}
87+
}
7888
err.emit();
89+
90+
}
7991
}
80-
}
8192

8293
fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>)
8394
-> Vec<GroupedMoveErrors<'tcx>> {

src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs

-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ fn c() {
5454
_ => {}
5555
}
5656
let a = vec[0]; //~ ERROR cannot move out
57-
//~^ NOTE to prevent move
5857
//~| cannot move out of here
5958
}
6059

@@ -68,7 +67,6 @@ fn d() {
6867
_ => {}
6968
}
7069
let a = vec[0]; //~ ERROR cannot move out
71-
//~^ NOTE to prevent move
7270
//~| cannot move out of here
7371
}
7472

@@ -84,7 +82,6 @@ fn e() {
8482
_ => {}
8583
}
8684
let a = vec[0]; //~ ERROR cannot move out
87-
//~^ NOTE to prevent move
8885
//~| cannot move out of here
8986
}
9087

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo {
12+
pub v: Vec<String>,
13+
}
14+
15+
fn main() {
16+
let mut f = Foo { v: Vec::new() };
17+
f.v.push("hello".to_string());
18+
let e = f.v[0];
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error[E0507]: cannot move out of indexed content
2+
--> $DIR/issue-40402-1.rs:18:13
3+
|
4+
18 | let e = f.v[0];
5+
| ^^^^^^ cannot move out of indexed content
6+
7+
error: aborting due to previous error
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let x = vec![(String::new(), String::new())];
13+
let (a, b) = x[0];
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0507]: cannot move out of indexed content
2+
--> $DIR/issue-40402-2.rs:13:18
3+
|
4+
13 | let (a, b) = x[0];
5+
| - - ^^^^ cannot move out of indexed content
6+
| | |
7+
| | ...and here (use `ref b` or `ref mut b`)
8+
| hint: to prevent move, use `ref a` or `ref mut a`
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)