diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2018-09-15 12:29:29 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2018-09-17 13:38:04 -0300 |
| commit | e9029cec7b7acf4e94aaef051bb85aabee64394a (patch) | |
| tree | a22a5f51f1b782d5832dbe0bfffc49002eeb2f48 | |
| parent | f1aefb48d2ec7ac38a66c964396a5aec729b7a28 (diff) | |
| download | rust-e9029cec7b7acf4e94aaef051bb85aabee64394a.tar.gz rust-e9029cec7b7acf4e94aaef051bb85aabee64394a.zip | |
Inspect parents paths when checking for moves
| -rw-r--r-- | src/librustc_mir/borrow_check/error_reporting.rs | 13 | ||||
| -rw-r--r-- | src/librustc_mir/dataflow/move_paths/mod.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/nll/issue-52669.rs | 28 | ||||
| -rw-r--r-- | src/test/ui/nll/issue-52669.stderr | 13 | ||||
| -rw-r--r-- | src/test/ui/nll/move-subpaths-moves-root.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/nll/move-subpaths-moves-root.stderr | 13 |
6 files changed, 97 insertions, 1 deletions
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 4671332f282..b52a9c16ff7 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -564,9 +564,20 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // created by `StorageDead` and at the beginning // of a function. } else { + // If we are found a use of a.b.c which was in error, then we want to look for + // moves not only of a.b.c but also a.b and a. + // + // Note that the moves data already includes "parent" paths, so we don't have to + // worry about the other case: that is, if there is a move of a.b.c, it is already + // marked as a move of a.b and a as well, so we will generate the correct errors + // there. + let mut mpis = vec![mpi]; + let move_paths = &self.move_data.move_paths; + mpis.extend(move_paths[mpi].parents(move_paths)); + for moi in &self.move_data.loc_map[l] { debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi); - if self.move_data.moves[*moi].path == mpi { + if mpis.contains(&self.move_data.moves[*moi].path) { debug!("report_use_of_moved_or_uninitialized: found"); result.push(*moi); diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 7d7da6c96e8..58a2b936103 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -97,6 +97,20 @@ pub struct MovePath<'tcx> { pub place: Place<'tcx>, } +impl<'tcx> MovePath<'tcx> { + pub fn parents(&self, move_paths: &IndexVec<MovePathIndex, MovePath>) -> Vec<MovePathIndex> { + let mut parents = Vec::new(); + + let mut curr_parent = self.parent; + while let Some(parent_mpi) = curr_parent { + parents.push(parent_mpi); + curr_parent = move_paths[parent_mpi].parent; + } + + parents + } +} + impl<'tcx> fmt::Debug for MovePath<'tcx> { fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { write!(w, "MovePath {{")?; diff --git a/src/test/ui/nll/issue-52669.rs b/src/test/ui/nll/issue-52669.rs new file mode 100644 index 00000000000..17a59997e91 --- /dev/null +++ b/src/test/ui/nll/issue-52669.rs @@ -0,0 +1,28 @@ +// Copyright 2018 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. + +#![feature(nll)] + +struct A { + b: B, +} + +#[derive(Clone)] +struct B; + +fn foo(_: A) {} + +fn bar(mut a: A) -> B { + a.b = B; + foo(a); + a.b.clone() +} + +fn main() {} diff --git a/src/test/ui/nll/issue-52669.stderr b/src/test/ui/nll/issue-52669.stderr new file mode 100644 index 00000000000..ca1576fad7a --- /dev/null +++ b/src/test/ui/nll/issue-52669.stderr @@ -0,0 +1,13 @@ +error[E0382]: borrow of moved value: `a.b` + --> $DIR/issue-52669.rs:25:5 + | +LL | foo(a); + | - value moved here +LL | a.b.clone() + | ^^^ value borrowed here after move + | + = note: move occurs because `a` has type `A`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/nll/move-subpaths-moves-root.rs b/src/test/ui/nll/move-subpaths-moves-root.rs new file mode 100644 index 00000000000..7a4e518f977 --- /dev/null +++ b/src/test/ui/nll/move-subpaths-moves-root.rs @@ -0,0 +1,17 @@ +// Copyright 2018 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. + +#![feature(nll)] + +fn main() { + let x = (vec![1, 2, 3], ); + drop(x.0); + drop(x); +} diff --git a/src/test/ui/nll/move-subpaths-moves-root.stderr b/src/test/ui/nll/move-subpaths-moves-root.stderr new file mode 100644 index 00000000000..76a1279750f --- /dev/null +++ b/src/test/ui/nll/move-subpaths-moves-root.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value: `x` + --> $DIR/move-subpaths-moves-root.rs:16:10 + | +LL | drop(x.0); + | --- value moved here +LL | drop(x); + | ^ value used here after move + | + = note: move occurs because `x.0` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. |
