Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,8 +851,21 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,
},
// Only relevant for mir typeck
StatementKind::AscribeUserType(..) => {}
// Only relevant for liveness and unsafeck
StatementKind::PlaceMention(..) => {}
// Only relevant for liveness and unsafeck,
// except for dereferences which must be materialized
StatementKind::PlaceMention(place) => {
if let Some((dereferenced_place, _)) = place
.iter_projections()
.rfind(|(_, proj)| matches!(proj, ProjectionElem::Deref))
{
self.check_if_full_path_is_moved(
location,
InitializationRequiringAction::Use,
(dereferenced_place, span),
state,
);
}
}
// Doesn't have any language semantics
StatementKind::Coverage(..) => {}
// These do not actually affect borrowck
Expand Down
5 changes: 5 additions & 0 deletions src/tools/miri/tests/pass/placemention-box-deref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() {
let x = Box::new(Box::new(Box::new(0)));
drop(**x);
_ = **x;
}
42 changes: 42 additions & 0 deletions tests/ui/borrowck/placemention-deref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
enum Thing {
Wut,
}

struct A(Box<A>);

fn main() {
let x: &'static String;
let _ = *x;
//~^ ERROR used binding `x` isn't initialized

let x: &Thing;
let Thing::Wut = *x;
//~^ ERROR used binding `x` isn't initialized

let x = Box::new(1);
drop(x);
_ = *x;
//~^ ERROR use of moved value: `x`

let x: A;
_ = x.0.0.0.0.0;
//~^ ERROR used binding `x` isn't initialized

let x: A;
let _ = x.0.0;
//~^ ERROR used binding `x` isn't initialized

let x = Box::new(Box::new(Box::new(Box::new(Box::new(Box::new(1))))));
drop(x);
_ = ******x;
Comment thread
Jules-Bertholet marked this conversation as resolved.
Resolved
//~^ ERROR use of moved value: `x`

let x = Box::new(Box::new(Box::new(0)));
drop(**x);
_ = ***x;
//~^ ERROR use of moved value: `**x`

let x = Box::new(Box::new(Box::new(0)));
drop(**x);
_ = **x; // OK
}
96 changes: 96 additions & 0 deletions tests/ui/borrowck/placemention-deref.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
error[E0381]: used binding `x` isn't initialized
--> $DIR/placemention-deref.rs:9:13
|
LL | let x: &'static String;
| - binding declared here but left uninitialized
LL | let _ = *x;
| ^^ `x` used here but it isn't initialized
|
help: consider assigning a value
|
LL | let x: &'static String = &Default::default();
| +++++++++++++++++++++

error[E0381]: used binding `x` isn't initialized
--> $DIR/placemention-deref.rs:13:22
|
LL | let x: &Thing;
| - binding declared here but left uninitialized
LL | let Thing::Wut = *x;
| ^^ `x` used here but it isn't initialized
|
help: consider assigning a value
|
LL | let x: &Thing = &/* value */;
| ++++++++++++++

error[E0382]: use of moved value: `x`
--> $DIR/placemention-deref.rs:18:9
|
LL | let x = Box::new(1);
| - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
LL | drop(x);
| - value moved here
LL | _ = *x;
| ^^ value used here after move
|
help: consider cloning the value if the performance cost is acceptable
|
LL | drop(x.clone());
| ++++++++

error[E0381]: used binding `x` isn't initialized
--> $DIR/placemention-deref.rs:22:9
|
LL | let x: A;
| - binding declared here but left uninitialized
LL | _ = x.0.0.0.0.0;
| ^^^^^^^^^^^ `x.0.0.0.0` used here but it isn't initialized
|
help: consider assigning a value
|
LL | let x: A = /* value */;
| +++++++++++++

error[E0381]: used binding `x` isn't initialized
--> $DIR/placemention-deref.rs:26:13
|
LL | let x: A;
| - binding declared here but left uninitialized
LL | let _ = x.0.0;
| ^^^^^ `x.0` used here but it isn't initialized
|
help: consider assigning a value
|
LL | let x: A = /* value */;
| +++++++++++++

error[E0382]: use of moved value: `x`
--> $DIR/placemention-deref.rs:31:9
|
LL | let x = Box::new(Box::new(Box::new(Box::new(Box::new(Box::new(1))))));
| - move occurs because `x` has type `Box<Box<Box<Box<Box<Box<i32>>>>>>`, which does not implement the `Copy` trait
LL | drop(x);
| - value moved here
LL | _ = ******x;
| ^^^^^^^ value used here after move
|
help: consider cloning the value if the performance cost is acceptable
|
LL | drop(x.clone());
| ++++++++

error[E0382]: use of moved value: `**x`
--> $DIR/placemention-deref.rs:36:9
|
LL | drop(**x);
| --- value moved here
LL | _ = ***x;
| ^^^^ value used here after move
|
= note: move occurs because `**x` has type `Box<i32>`, which does not implement the `Copy` trait

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0381, E0382.
For more information about an error, try `rustc --explain E0381`.
Loading