Skip to content

Commit 0560747

Browse files
committed
Auto merge of #52678 - matthewjasper:better-spans, r=nikomatsakis
[NLL] Use better spans in some errors * Use the span of the discriminant and patterns for "fake" statements created to properly check matches. I plan to special case these soon, but this felt like a good first step * Use the span of the statement, rather than the initialization, when reporting move errors for `let x = ...`, which avoids giving an unhelpful suggestion to use `&{ }`. r? @nikomatsakis cc @pnkfelix
2 parents 4f1e235 + b32caef commit 0560747

15 files changed

+295
-162
lines changed

src/librustc_mir/borrow_check/move_errors.rs

+19-24
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
8787
cannot_move_out_of: IllegalMoveOrigin { location, kind },
8888
} => {
8989
let stmt_source_info = self.mir.source_info(location);
90+
// Note: that the only time we assign a place isn't a temporary
91+
// to a user variable is when initializing it.
92+
// If that ever stops being the case, then the ever initialized
93+
// flow could be used.
9094
if let Some(StatementKind::Assign(
9195
Place::Local(local),
9296
Rvalue::Use(Operand::Move(move_from)),
@@ -109,26 +113,16 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
109113
opt_ty_info: _,
110114
}))) = local_decl.is_user_variable
111115
{
112-
// HACK use scopes to determine if this assignment is
113-
// the initialization of a variable.
114-
// FIXME(matthewjasper) This would probably be more
115-
// reliable if it used the ever initialized dataflow
116-
// but move errors are currently reported before the
117-
// rest of borrowck has run.
118-
if self
119-
.mir
120-
.is_sub_scope(local_decl.source_info.scope, stmt_source_info.scope)
121-
{
122-
self.append_binding_error(
123-
grouped_errors,
124-
kind,
125-
move_from,
126-
*local,
127-
opt_match_place,
128-
match_span,
129-
);
130-
return;
131-
}
116+
self.append_binding_error(
117+
grouped_errors,
118+
kind,
119+
move_from,
120+
*local,
121+
opt_match_place,
122+
match_span,
123+
stmt_source_info.span,
124+
);
125+
return;
132126
}
133127
}
134128
grouped_errors.push(GroupedMoveError::OtherIllegalMove {
@@ -147,6 +141,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
147141
bind_to: Local,
148142
match_place: &Option<Place<'tcx>>,
149143
match_span: Span,
144+
statement_span: Span,
150145
) {
151146
debug!(
152147
"append_to_grouped_errors(match_place={:?}, match_span={:?})",
@@ -173,13 +168,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
173168
debug!("found a new move error location");
174169

175170
// Don't need to point to x in let x = ... .
176-
let binds_to = if from_simple_let {
177-
vec![]
171+
let (binds_to, span) = if from_simple_let {
172+
(vec![], statement_span)
178173
} else {
179-
vec![bind_to]
174+
(vec![bind_to], match_span)
180175
};
181176
grouped_errors.push(GroupedMoveError::MovesFromMatchPlace {
182-
span: match_span,
177+
span,
183178
move_from: match_place.clone(),
184179
kind,
185180
binds_to,

src/librustc_mir/build/matches/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6363
// injects a borrow of the matched input, which should have the same effect
6464
// as eddyb's hack. Once NLL is the default, we can remove the hack.
6565

66-
let dummy_source_info = self.source_info(span);
66+
let dummy_source_info = self.source_info(discriminant_span);
6767
let dummy_access = Rvalue::Discriminant(discriminant_place.clone());
6868
let dummy_ty = dummy_access.ty(&self.local_decls, tcx);
6969
let dummy_temp = self.temp(dummy_ty, dummy_source_info.span);
7070
self.cfg.push_assign(block, dummy_source_info, &dummy_temp, dummy_access);
7171

72-
let source_info = self.source_info(span);
72+
let source_info = self.source_info(discriminant_span);
7373
let borrowed_input_temp = if tcx.generate_borrow_of_any_match_input() {
7474
// The region is unknown at this point; we rely on NLL
7575
// inference to find an appropriate one. Therefore you can
@@ -136,9 +136,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
136136
// This should ensure that you cannot change
137137
// the variant for an enum while you are in
138138
// the midst of matching on it.
139-
139+
let pattern_source_info = self.source_info(pattern.span);
140140
self.cfg.push(*pre_binding_block, Statement {
141-
source_info,
141+
source_info: pattern_source_info,
142142
kind: StatementKind::ReadForMatch(borrow_temp.clone()),
143143
});
144144
}

src/test/ui/borrowck/issue-41962.stderr

+10-14
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,22 @@ LL | if let Some(thing) = maybe {
1717
= note: move occurs because the value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
1818

1919
error[E0382]: use of moved value: `maybe` (Mir)
20-
--> $DIR/issue-41962.rs:17:9
20+
--> $DIR/issue-41962.rs:17:30
2121
|
22-
LL | if let Some(thing) = maybe {
23-
| ^ ----- value moved here
24-
| _________|
25-
| |
26-
LL | | }
27-
| |_________^ value used here after move
22+
LL | if let Some(thing) = maybe {
23+
| ----- ^^^^^ value used here after move
24+
| |
25+
| value moved here
2826
|
2927
= note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
3028

3129
error[E0382]: borrow of moved value: `maybe` (Mir)
32-
--> $DIR/issue-41962.rs:17:9
30+
--> $DIR/issue-41962.rs:17:30
3331
|
34-
LL | if let Some(thing) = maybe {
35-
| ^ ----- value moved here
36-
| _________|
37-
| |
38-
LL | | }
39-
| |_________^ value borrowed here after move
32+
LL | if let Some(thing) = maybe {
33+
| ----- ^^^^^ value borrowed here after move
34+
| |
35+
| value moved here
4036
|
4137
= note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
4238

src/test/ui/issue-17385.nll.stderr

+20-32
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
error[E0382]: use of moved value: `foo`
2-
--> $DIR/issue-17385.rs:28:5
2+
--> $DIR/issue-17385.rs:28:11
33
|
4-
LL | drop(foo);
5-
| --- value moved here
6-
LL | / match foo { //~ ERROR use of moved value
7-
LL | | X(1) => (),
8-
LL | | _ => unreachable!()
9-
LL | | }
10-
| |_____^ value used here after move
4+
LL | drop(foo);
5+
| --- value moved here
6+
LL | match foo { //~ ERROR use of moved value
7+
| ^^^ value used here after move
118
|
129
= note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait
1310

1411
error[E0382]: borrow of moved value: `foo`
15-
--> $DIR/issue-17385.rs:28:5
12+
--> $DIR/issue-17385.rs:28:11
1613
|
17-
LL | drop(foo);
18-
| --- value moved here
19-
LL | / match foo { //~ ERROR use of moved value
20-
LL | | X(1) => (),
21-
LL | | _ => unreachable!()
22-
LL | | }
23-
| |_____^ value borrowed here after move
14+
LL | drop(foo);
15+
| --- value moved here
16+
LL | match foo { //~ ERROR use of moved value
17+
| ^^^ value borrowed here after move
2418
|
2519
= note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait
2620

@@ -36,28 +30,22 @@ LL | X(1) => (),
3630
= note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait
3731

3832
error[E0382]: use of moved value: `e`
39-
--> $DIR/issue-17385.rs:35:5
33+
--> $DIR/issue-17385.rs:35:11
4034
|
41-
LL | drop(e);
42-
| - value moved here
43-
LL | / match e { //~ ERROR use of moved value
44-
LL | | Enum::Variant1 => unreachable!(),
45-
LL | | Enum::Variant2 => ()
46-
LL | | }
47-
| |_____^ value used here after move
35+
LL | drop(e);
36+
| - value moved here
37+
LL | match e { //~ ERROR use of moved value
38+
| ^ value used here after move
4839
|
4940
= note: move occurs because `e` has type `Enum`, which does not implement the `Copy` trait
5041

5142
error[E0382]: borrow of moved value: `e`
52-
--> $DIR/issue-17385.rs:35:5
43+
--> $DIR/issue-17385.rs:35:11
5344
|
54-
LL | drop(e);
55-
| - value moved here
56-
LL | / match e { //~ ERROR use of moved value
57-
LL | | Enum::Variant1 => unreachable!(),
58-
LL | | Enum::Variant2 => ()
59-
LL | | }
60-
| |_____^ value borrowed here after move
45+
LL | drop(e);
46+
| - value moved here
47+
LL | match e { //~ ERROR use of moved value
48+
| ^ value borrowed here after move
6149
|
6250
= note: move occurs because `e` has type `Enum`, which does not implement the `Copy` trait
6351

src/test/ui/issue-20801.nll.stderr

+16-4
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,37 @@ error[E0507]: cannot move out of borrowed content
22
--> $DIR/issue-20801.rs:36:22
33
|
44
LL | let a = unsafe { *mut_ref() };
5-
| ^^^^^^^^^^ cannot move out of borrowed content
5+
| ^^^^^^^^^^
6+
| |
7+
| cannot move out of borrowed content
8+
| help: consider using a reference instead: `&*mut_ref()`
69

710
error[E0507]: cannot move out of borrowed content
811
--> $DIR/issue-20801.rs:39:22
912
|
1013
LL | let b = unsafe { *imm_ref() };
11-
| ^^^^^^^^^^ cannot move out of borrowed content
14+
| ^^^^^^^^^^
15+
| |
16+
| cannot move out of borrowed content
17+
| help: consider using a reference instead: `&*imm_ref()`
1218

1319
error[E0507]: cannot move out of borrowed content
1420
--> $DIR/issue-20801.rs:42:22
1521
|
1622
LL | let c = unsafe { *mut_ptr() };
17-
| ^^^^^^^^^^ cannot move out of borrowed content
23+
| ^^^^^^^^^^
24+
| |
25+
| cannot move out of borrowed content
26+
| help: consider using a reference instead: `&*mut_ptr()`
1827

1928
error[E0507]: cannot move out of borrowed content
2029
--> $DIR/issue-20801.rs:45:22
2130
|
2231
LL | let d = unsafe { *const_ptr() };
23-
| ^^^^^^^^^^^^ cannot move out of borrowed content
32+
| ^^^^^^^^^^^^
33+
| |
34+
| cannot move out of borrowed content
35+
| help: consider using a reference instead: `&*const_ptr()`
2436

2537
error: aborting due to 4 previous errors
2638

src/test/ui/issue-27282-move-match-input-into-guard.stderr

+8-15
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
error[E0505]: cannot move out of `b` because it is borrowed
22
--> $DIR/issue-27282-move-match-input-into-guard.rs:26:16
33
|
4-
LL | match b {
5-
| _____-
6-
| |_____|
7-
| ||
8-
LL | || &mut false => {},
9-
LL | || _ if { (|| { let bar = b; *bar = false; })();
10-
| || ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here
11-
LL | || //~^ ERROR cannot move out of `b` because it is borrowed [E0505]
12-
... ||
13-
LL | || _ => panic!("surely we could never get here, since rustc warns it is unreachable."),
14-
LL | || }
15-
| || -
16-
| ||_____|
17-
| |______borrow of `b` occurs here
18-
| borrow later used here
4+
LL | match b {
5+
| - borrow of `b` occurs here
6+
LL | &mut false => {},
7+
LL | _ if { (|| { let bar = b; *bar = false; })();
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here
9+
...
10+
LL | &mut true => { println!("You might think we should get here"); },
11+
| --------- borrow later used here
1912

2013
error[E0382]: use of moved value: `*b`
2114
--> $DIR/issue-27282-move-match-input-into-guard.rs:29:14

src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr

+10-18
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,16 @@
11
error[E0500]: closure requires unique access to `x` but it is already borrowed
22
--> $DIR/issue-27282-mutate-before-diverging-arm-1.rs:33:14
33
|
4-
LL | match x {
5-
| _____-
6-
| |_____|
7-
| ||
8-
LL | || &mut None => panic!("unreachable"),
9-
LL | || &mut Some(&_) if {
10-
LL | || // ForceFnOnce needed to exploit #27282
11-
LL | || (|| { *x = None; drop(force_fn_once); })();
12-
| || ^^ - borrow occurs due to use of `x` in closure
13-
| || |
14-
| || closure construction occurs here
15-
... ||
16-
LL | || _ => panic!("unreachable"),
17-
LL | || }
18-
| || -
19-
| ||_____|
20-
| |______borrow occurs here
21-
| borrow later used here
4+
LL | match x {
5+
| - borrow occurs here
6+
...
7+
LL | (|| { *x = None; drop(force_fn_once); })();
8+
| ^^ - borrow occurs due to use of `x` in closure
9+
| |
10+
| closure construction occurs here
11+
...
12+
LL | &mut Some(&a) if { // this binds to garbage if we've corrupted discriminant
13+
| ------------- borrow later used here
2214

2315
error: aborting due to previous error
2416

src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr

+10-19
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,16 @@
11
error[E0500]: closure requires unique access to `x` but it is already borrowed
22
--> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:38:18
33
|
4-
LL | match x {
5-
| _____-
6-
| |_____|
7-
| ||
8-
LL | || &mut None => panic!("unreachable"),
9-
LL | || &mut Some(&_)
10-
LL | || if {
11-
LL | || // ForceFnOnce needed to exploit #27282
12-
LL | || (|| { *x = None; drop(force_fn_once); })();
13-
| || ^^ - borrow occurs due to use of `x` in closure
14-
| || |
15-
| || closure construction occurs here
16-
... ||
17-
LL | || _ => panic!("unreachable"),
18-
LL | || }
19-
| || -
20-
| ||_____|
21-
| |______borrow occurs here
22-
| borrow later used here
4+
LL | match x {
5+
| - borrow occurs here
6+
...
7+
LL | (|| { *x = None; drop(force_fn_once); })();
8+
| ^^ - borrow occurs due to use of `x` in closure
9+
| |
10+
| closure construction occurs here
11+
...
12+
LL | &mut Some(&2)
13+
| ------------- borrow later used here
2314

2415
error: aborting due to previous error
2516

src/test/ui/issue-47412.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
error[E0133]: access to union field is unsafe and requires unsafe function or block
2-
--> $DIR/issue-47412.rs:21:5
2+
--> $DIR/issue-47412.rs:21:11
33
|
44
LL | match u.void {}
5-
| ^^^^^^^^^^^^^^^ access to union field
5+
| ^^^^^^ access to union field
66
|
77
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
88

99
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
10-
--> $DIR/issue-47412.rs:27:5
10+
--> $DIR/issue-47412.rs:27:11
1111
|
1212
LL | match *ptr {}
13-
| ^^^^^^^^^^^^^ dereference of raw pointer
13+
| ^^^^ dereference of raw pointer
1414
|
1515
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
1616

0 commit comments

Comments
 (0)