Skip to content

Commit 26ad9e2

Browse files
Rollup merge of rust-lang#51247 - pnkfelix:issue-51190-report-type-moved-from-behind-borrow, r=nikomatsakis
NLL: report type moved from behind borrow of array/slice When NLL has illegal move due to borrowed content in an array or slice, provide feedback about why the move wasn't a copy. Drive by: While comparing the resulting `.nll.stderr` files to their old borrowck variants, I noticed that the test for borrowck-vec-pattern-nesting.rs was not signaling some errors under NLL due to the test assuming lexical lifetimes. So I fixed that too. Fix rust-lang#51190
2 parents 8ec9f4c + e99f5ec commit 26ad9e2

File tree

9 files changed

+105
-49
lines changed

9 files changed

+105
-49
lines changed

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
147147
}
148148
Categorization::Interior(ref b, mc::InteriorElement(ik)) => {
149149
bccx.cannot_move_out_of_interior_noncopy(
150-
move_from.span, b.ty, ik == Kind::Index, Origin::Ast)
150+
move_from.span, b.ty, Some(ik == Kind::Index), Origin::Ast)
151151
}
152152

153153
Categorization::Downcast(ref b, _) |

src/librustc_mir/borrow_check/mod.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,21 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
132132
IllegalMoveOriginKind::Static => {
133133
tcx.cannot_move_out_of(span, "static item", origin)
134134
}
135-
IllegalMoveOriginKind::BorrowedContent => {
136-
tcx.cannot_move_out_of(span, "borrowed content", origin)
135+
IllegalMoveOriginKind::BorrowedContent { target_ty: ty } => {
136+
// Inspect the type of the content behind the
137+
// borrow to provide feedback about why this
138+
// was a move rather than a copy.
139+
match ty.sty {
140+
ty::TyArray(..) | ty::TySlice(..) =>
141+
tcx.cannot_move_out_of_interior_noncopy(span, ty, None, origin),
142+
_ => tcx.cannot_move_out_of(span, "borrowed content", origin)
143+
}
137144
}
138145
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
139146
tcx.cannot_move_out_of_interior_of_drop(span, ty, origin)
140147
}
141148
IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
142-
tcx.cannot_move_out_of_interior_noncopy(span, ty, is_index, origin)
149+
tcx.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index), origin)
143150
}
144151
};
145152
err.emit();

src/librustc_mir/dataflow/move_paths/builder.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
119119
}
120120

121121
fn create_move_path(&mut self, place: &Place<'tcx>) {
122-
// This is an assignment, not a move, so this not being a valid
123-
// move path is OK.
122+
// This is an non-moving access (such as an overwrite or
123+
// drop), so this not being a valid move path is OK.
124124
let _ = self.move_path_for(place);
125125
}
126126

@@ -135,8 +135,9 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
135135
let place_ty = proj.base.ty(mir, tcx).to_ty(tcx);
136136
match place_ty.sty {
137137
ty::TyRef(..) | ty::TyRawPtr(..) =>
138-
return Err(MoveError::cannot_move_out_of(mir.source_info(self.loc).span,
139-
BorrowedContent)),
138+
return Err(MoveError::cannot_move_out_of(
139+
mir.source_info(self.loc).span,
140+
BorrowedContent { target_ty: place.ty(mir, tcx).to_ty(tcx) })),
140141
ty::TyAdt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
141142
return Err(MoveError::cannot_move_out_of(mir.source_info(self.loc).span,
142143
InteriorOfTypeWithDestructor {

src/librustc_mir/dataflow/move_paths/mod.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,23 @@ pub struct IllegalMoveOrigin<'tcx> {
277277

278278
#[derive(Debug)]
279279
pub(crate) enum IllegalMoveOriginKind<'tcx> {
280+
/// Illegal move due to attempt to move from `static` variable.
280281
Static,
281-
BorrowedContent,
282+
283+
/// Illegal move due to attempt to move from behind a reference.
284+
BorrowedContent {
285+
/// The content's type: if erroneous code was trying to move
286+
/// from `*x` where `x: &T`, then this will be `T`.
287+
target_ty: ty::Ty<'tcx>,
288+
},
289+
290+
/// Illegal move due to attempt to move from field of an ADT that
291+
/// implements `Drop`. Rust maintains invariant that all `Drop`
292+
/// ADT's remain fully-initialized so that user-defined destructor
293+
/// can safely read from all of the ADT's fields.
282294
InteriorOfTypeWithDestructor { container_ty: ty::Ty<'tcx> },
295+
296+
/// Illegal move due to attempt to move out of a slice or array.
283297
InteriorOfSliceOrArray { ty: ty::Ty<'tcx>, is_index: bool, },
284298
}
285299

src/librustc_mir/util/borrowck_errors.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -312,15 +312,19 @@ pub trait BorrowckErrors<'cx>: Sized + Copy {
312312
self.cancel_if_wrong_origin(err, o)
313313
}
314314

315+
/// Signal an error due to an attempt to move out of the interior
316+
/// of an array or slice. `is_index` is None when error origin
317+
/// didn't capture whether there was an indexing operation or not.
315318
fn cannot_move_out_of_interior_noncopy(self,
316319
move_from_span: Span,
317320
ty: ty::Ty,
318-
is_index: bool,
321+
is_index: Option<bool>,
319322
o: Origin)
320323
-> DiagnosticBuilder<'cx>
321324
{
322325
let type_name = match (&ty.sty, is_index) {
323-
(&ty::TyArray(_, _), true) => "array",
326+
(&ty::TyArray(_, _), Some(true)) |
327+
(&ty::TyArray(_, _), None) => "array",
324328
(&ty::TySlice(_), _) => "slice",
325329
_ => span_bug!(move_from_span, "this path should not cause illegal move"),
326330
};
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
error[E0507]: cannot move out of borrowed content
1+
error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
22
--> $DIR/borrowck-move-out-of-vec-tail.rs:30:33
33
|
44
LL | &[Foo { string: a },
5-
| ^ cannot move out of borrowed content
5+
| ^ cannot move out of here
66

7-
error[E0507]: cannot move out of borrowed content
7+
error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
88
--> $DIR/borrowck-move-out-of-vec-tail.rs:34:33
99
|
1010
LL | Foo { string: b }] => {
11-
| ^ cannot move out of borrowed content
11+
| ^ cannot move out of here
1212

1313
error: aborting due to 2 previous errors
1414

15-
For more information about this error, try `rustc --explain E0507`.
15+
For more information about this error, try `rustc --explain E0508`.
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,76 @@
1-
error[E0507]: cannot move out of borrowed content
2-
--> $DIR/borrowck-vec-pattern-nesting.rs:42:15
1+
error[E0506]: cannot assign to `vec[..]` because it is borrowed
2+
--> $DIR/borrowck-vec-pattern-nesting.rs:20:13
3+
|
4+
LL | [box ref _a, _, _] => {
5+
| ------ borrow of `vec[..]` occurs here
6+
LL | //~^ borrow of `vec[..]` occurs here
7+
LL | vec[0] = box 4; //~ ERROR cannot assign
8+
| ^^^^^^ assignment to borrowed `vec[..]` occurs here
9+
LL | //~^ assignment to borrowed `vec[..]` occurs here
10+
LL | _a.use_ref();
11+
| -- borrow later used here
12+
13+
error[E0506]: cannot assign to `vec[..]` because it is borrowed
14+
--> $DIR/borrowck-vec-pattern-nesting.rs:33:13
15+
|
16+
LL | &mut [ref _b..] => {
17+
| ------ borrow of `vec[..]` occurs here
18+
LL | //~^ borrow of `vec[..]` occurs here
19+
LL | vec[0] = box 4; //~ ERROR cannot assign
20+
| ^^^^^^ assignment to borrowed `vec[..]` occurs here
21+
LL | //~^ assignment to borrowed `vec[..]` occurs here
22+
LL | _b.use_ref();
23+
| -- borrow later used here
24+
25+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
26+
--> $DIR/borrowck-vec-pattern-nesting.rs:44:15
327
|
428
LL | &mut [_a, //~ ERROR cannot move out
5-
| ^^ cannot move out of borrowed content
29+
| ^^ cannot move out of here
630

7-
error[E0507]: cannot move out of borrowed content
8-
--> $DIR/borrowck-vec-pattern-nesting.rs:55:13
31+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
32+
--> $DIR/borrowck-vec-pattern-nesting.rs:57:13
933
|
1034
LL | let a = vec[0]; //~ ERROR cannot move out
11-
| ^^^^^^ cannot move out of borrowed content
35+
| ^^^^^^ cannot move out of here
1236

13-
error[E0507]: cannot move out of borrowed content
14-
--> $DIR/borrowck-vec-pattern-nesting.rs:65:10
37+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
38+
--> $DIR/borrowck-vec-pattern-nesting.rs:67:10
1539
|
1640
LL | _b] => {}
17-
| ^^ cannot move out of borrowed content
41+
| ^^ cannot move out of here
1842

19-
error[E0507]: cannot move out of borrowed content
20-
--> $DIR/borrowck-vec-pattern-nesting.rs:68:13
43+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
44+
--> $DIR/borrowck-vec-pattern-nesting.rs:70:13
2145
|
2246
LL | let a = vec[0]; //~ ERROR cannot move out
23-
| ^^^^^^ cannot move out of borrowed content
47+
| ^^^^^^ cannot move out of here
2448

25-
error[E0507]: cannot move out of borrowed content
26-
--> $DIR/borrowck-vec-pattern-nesting.rs:76:15
49+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
50+
--> $DIR/borrowck-vec-pattern-nesting.rs:78:15
2751
|
2852
LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
29-
| ^^ cannot move out of borrowed content
53+
| ^^ cannot move out of here
3054

31-
error[E0507]: cannot move out of borrowed content
32-
--> $DIR/borrowck-vec-pattern-nesting.rs:76:19
55+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
56+
--> $DIR/borrowck-vec-pattern-nesting.rs:78:19
3357
|
3458
LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
35-
| ^^ cannot move out of borrowed content
59+
| ^^ cannot move out of here
3660

37-
error[E0507]: cannot move out of borrowed content
38-
--> $DIR/borrowck-vec-pattern-nesting.rs:76:23
61+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
62+
--> $DIR/borrowck-vec-pattern-nesting.rs:78:23
3963
|
4064
LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
41-
| ^^ cannot move out of borrowed content
65+
| ^^ cannot move out of here
4266

43-
error[E0507]: cannot move out of borrowed content
44-
--> $DIR/borrowck-vec-pattern-nesting.rs:80:13
67+
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
68+
--> $DIR/borrowck-vec-pattern-nesting.rs:82:13
4569
|
4670
LL | let a = vec[0]; //~ ERROR cannot move out
47-
| ^^^^^^ cannot move out of borrowed content
71+
| ^^^^^^ cannot move out of here
4872

49-
error: aborting due to 8 previous errors
73+
error: aborting due to 10 previous errors
5074

51-
For more information about this error, try `rustc --explain E0507`.
75+
Some errors occurred: E0506, E0508.
76+
For more information about an error, try `rustc --explain E0506`.

src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ fn a() {
1919
//~^ borrow of `vec[..]` occurs here
2020
vec[0] = box 4; //~ ERROR cannot assign
2121
//~^ assignment to borrowed `vec[..]` occurs here
22+
_a.use_ref();
2223
}
2324
}
2425
}
@@ -31,6 +32,7 @@ fn b() {
3132
//~^ borrow of `vec[..]` occurs here
3233
vec[0] = box 4; //~ ERROR cannot assign
3334
//~^ assignment to borrowed `vec[..]` occurs here
35+
_b.use_ref();
3436
}
3537
}
3638
}
@@ -82,3 +84,6 @@ fn e() {
8284
}
8385

8486
fn main() {}
87+
88+
trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
89+
impl<T> Fake for T { }

src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | vec[0] = box 4; //~ ERROR cannot assign
88
| ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here
99

1010
error[E0506]: cannot assign to `vec[..]` because it is borrowed
11-
--> $DIR/borrowck-vec-pattern-nesting.rs:32:13
11+
--> $DIR/borrowck-vec-pattern-nesting.rs:33:13
1212
|
1313
LL | &mut [ref _b..] => {
1414
| ------ borrow of `vec[..]` occurs here
@@ -17,7 +17,7 @@ LL | vec[0] = box 4; //~ ERROR cannot assign
1717
| ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here
1818

1919
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
20-
--> $DIR/borrowck-vec-pattern-nesting.rs:42:14
20+
--> $DIR/borrowck-vec-pattern-nesting.rs:44:14
2121
|
2222
LL | &mut [_a, //~ ERROR cannot move out
2323
| ^-- hint: to prevent move, use `ref _a` or `ref mut _a`
@@ -30,7 +30,7 @@ LL | | ] => {
3030
| |_________^ cannot move out of here
3131

3232
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
33-
--> $DIR/borrowck-vec-pattern-nesting.rs:55:13
33+
--> $DIR/borrowck-vec-pattern-nesting.rs:57:13
3434
|
3535
LL | let a = vec[0]; //~ ERROR cannot move out
3636
| ^^^^^^
@@ -39,7 +39,7 @@ LL | let a = vec[0]; //~ ERROR cannot move out
3939
| help: consider using a reference instead: `&vec[0]`
4040

4141
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
42-
--> $DIR/borrowck-vec-pattern-nesting.rs:63:14
42+
--> $DIR/borrowck-vec-pattern-nesting.rs:65:14
4343
|
4444
LL | &mut [ //~ ERROR cannot move out
4545
| ______________^
@@ -50,7 +50,7 @@ LL | | _b] => {}
5050
| hint: to prevent move, use `ref _b` or `ref mut _b`
5151

5252
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
53-
--> $DIR/borrowck-vec-pattern-nesting.rs:68:13
53+
--> $DIR/borrowck-vec-pattern-nesting.rs:70:13
5454
|
5555
LL | let a = vec[0]; //~ ERROR cannot move out
5656
| ^^^^^^
@@ -59,7 +59,7 @@ LL | let a = vec[0]; //~ ERROR cannot move out
5959
| help: consider using a reference instead: `&vec[0]`
6060

6161
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
62-
--> $DIR/borrowck-vec-pattern-nesting.rs:76:14
62+
--> $DIR/borrowck-vec-pattern-nesting.rs:78:14
6363
|
6464
LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
6565
| ^--^^--^^--^
@@ -70,7 +70,7 @@ LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
7070
| cannot move out of here
7171

7272
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
73-
--> $DIR/borrowck-vec-pattern-nesting.rs:80:13
73+
--> $DIR/borrowck-vec-pattern-nesting.rs:82:13
7474
|
7575
LL | let a = vec[0]; //~ ERROR cannot move out
7676
| ^^^^^^

0 commit comments

Comments
 (0)