Skip to content

Commit f7f4c50

Browse files
committedSep 20, 2018
Auto merge of #54255 - spastorino:use-of-moved-value-error, r=nikomatsakis
Inspect parents paths when checking for moves Closes #52669
2 parents 992d1e4 + e9029ce commit f7f4c50

File tree

6 files changed

+97
-1
lines changed

6 files changed

+97
-1
lines changed
 

‎src/librustc_mir/borrow_check/error_reporting.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -584,9 +584,20 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
584584
// created by `StorageDead` and at the beginning
585585
// of a function.
586586
} else {
587+
// If we are found a use of a.b.c which was in error, then we want to look for
588+
// moves not only of a.b.c but also a.b and a.
589+
//
590+
// Note that the moves data already includes "parent" paths, so we don't have to
591+
// worry about the other case: that is, if there is a move of a.b.c, it is already
592+
// marked as a move of a.b and a as well, so we will generate the correct errors
593+
// there.
594+
let mut mpis = vec![mpi];
595+
let move_paths = &self.move_data.move_paths;
596+
mpis.extend(move_paths[mpi].parents(move_paths));
597+
587598
for moi in &self.move_data.loc_map[l] {
588599
debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi);
589-
if self.move_data.moves[*moi].path == mpi {
600+
if mpis.contains(&self.move_data.moves[*moi].path) {
590601
debug!("report_use_of_moved_or_uninitialized: found");
591602
result.push(*moi);
592603

‎src/librustc_mir/dataflow/move_paths/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,20 @@ pub struct MovePath<'tcx> {
9797
pub place: Place<'tcx>,
9898
}
9999

100+
impl<'tcx> MovePath<'tcx> {
101+
pub fn parents(&self, move_paths: &IndexVec<MovePathIndex, MovePath>) -> Vec<MovePathIndex> {
102+
let mut parents = Vec::new();
103+
104+
let mut curr_parent = self.parent;
105+
while let Some(parent_mpi) = curr_parent {
106+
parents.push(parent_mpi);
107+
curr_parent = move_paths[parent_mpi].parent;
108+
}
109+
110+
parents
111+
}
112+
}
113+
100114
impl<'tcx> fmt::Debug for MovePath<'tcx> {
101115
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
102116
write!(w, "MovePath {{")?;

‎src/test/ui/nll/issue-52669.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2018 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+
#![feature(nll)]
12+
13+
struct A {
14+
b: B,
15+
}
16+
17+
#[derive(Clone)]
18+
struct B;
19+
20+
fn foo(_: A) {}
21+
22+
fn bar(mut a: A) -> B {
23+
a.b = B;
24+
foo(a);
25+
a.b.clone()
26+
}
27+
28+
fn main() {}

‎src/test/ui/nll/issue-52669.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0382]: borrow of moved value: `a.b`
2+
--> $DIR/issue-52669.rs:25:5
3+
|
4+
LL | foo(a);
5+
| - value moved here
6+
LL | a.b.clone()
7+
| ^^^ value borrowed here after move
8+
|
9+
= note: move occurs because `a` has type `A`, which does not implement the `Copy` trait
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0382`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2018 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+
#![feature(nll)]
12+
13+
fn main() {
14+
let x = (vec![1, 2, 3], );
15+
drop(x.0);
16+
drop(x);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0382]: use of moved value: `x`
2+
--> $DIR/move-subpaths-moves-root.rs:16:10
3+
|
4+
LL | drop(x.0);
5+
| --- value moved here
6+
LL | drop(x);
7+
| ^ value used here after move
8+
|
9+
= note: move occurs because `x.0` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0382`.

0 commit comments

Comments
 (0)
Please sign in to comment.