mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
Don't suppress move errors for union fields
This commit is contained in:
parent
c8ea4ace92
commit
97219d87fe
@ -103,6 +103,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
// The move path index of the first union that we find. Once this is
|
||||
// some we stop creating child move paths, since moves from unions
|
||||
// move the whole thing.
|
||||
// We continue looking for other move errors though so that moving
|
||||
// from `*(u.f: &_)` isn't allowed.
|
||||
let mut union_path = None;
|
||||
|
||||
for (i, elem) in place.projection.iter().enumerate() {
|
||||
let proj_base = &place.projection[..i];
|
||||
let body = self.builder.body;
|
||||
@ -127,9 +134,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
InteriorOfTypeWithDestructor { container_ty: place_ty },
|
||||
));
|
||||
}
|
||||
// move out of union - always move the entire union
|
||||
ty::Adt(adt, _) if adt.is_union() => {
|
||||
return Err(MoveError::UnionMove { path: base });
|
||||
union_path.get_or_insert(base);
|
||||
}
|
||||
ty::Slice(_) => {
|
||||
return Err(MoveError::cannot_move_out_of(
|
||||
@ -155,15 +161,22 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
_ => {}
|
||||
};
|
||||
|
||||
base = self.add_move_path(base, elem, |tcx| {
|
||||
Place {
|
||||
base: place.base.clone(),
|
||||
projection: tcx.intern_place_elems(&place.projection[..i+1]),
|
||||
}
|
||||
});
|
||||
if union_path.is_none() {
|
||||
base = self.add_move_path(base, elem, |tcx| {
|
||||
Place {
|
||||
base: place.base.clone(),
|
||||
projection: tcx.intern_place_elems(&place.projection[..i+1]),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(base)
|
||||
if let Some(base) = union_path {
|
||||
// Move out of union - always move the entire union.
|
||||
Err(MoveError::UnionMove { path: base })
|
||||
} else {
|
||||
Ok(base)
|
||||
}
|
||||
}
|
||||
|
||||
fn add_move_path(
|
||||
|
30
src/test/ui/borrowck/move-from-union-field-issue-66500.rs
Normal file
30
src/test/ui/borrowck/move-from-union-field-issue-66500.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// Moving from a reference/raw pointer should be an error, even when they're
|
||||
// the field of a union.
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
|
||||
union Pointers {
|
||||
a: &'static String,
|
||||
b: &'static mut String,
|
||||
c: *const String,
|
||||
d: *mut String,
|
||||
}
|
||||
|
||||
unsafe fn move_ref(u: Pointers) -> String {
|
||||
*u.a
|
||||
//~^ ERROR cannot move out of `*u.a`
|
||||
}
|
||||
unsafe fn move_ref_mut(u: Pointers) -> String {
|
||||
*u.b
|
||||
//~^ ERROR cannot move out of `*u.b`
|
||||
}
|
||||
unsafe fn move_ptr(u: Pointers) -> String {
|
||||
*u.c
|
||||
//~^ ERROR cannot move out of `*u.c`
|
||||
}
|
||||
unsafe fn move_ptr_mut(u: Pointers) -> String {
|
||||
*u.d
|
||||
//~^ ERROR cannot move out of `*u.d`
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,27 @@
|
||||
error[E0507]: cannot move out of `*u.a` which is behind a shared reference
|
||||
--> $DIR/move-from-union-field-issue-66500.rs:14:5
|
||||
|
|
||||
LL | *u.a
|
||||
| ^^^^ move occurs because `*u.a` has type `std::string::String`, which does not implement the `Copy` trait
|
||||
|
||||
error[E0507]: cannot move out of `*u.b` which is behind a mutable reference
|
||||
--> $DIR/move-from-union-field-issue-66500.rs:18:5
|
||||
|
|
||||
LL | *u.b
|
||||
| ^^^^ move occurs because `*u.b` has type `std::string::String`, which does not implement the `Copy` trait
|
||||
|
||||
error[E0507]: cannot move out of `*u.c` which is behind a raw pointer
|
||||
--> $DIR/move-from-union-field-issue-66500.rs:22:5
|
||||
|
|
||||
LL | *u.c
|
||||
| ^^^^ move occurs because `*u.c` has type `std::string::String`, which does not implement the `Copy` trait
|
||||
|
||||
error[E0507]: cannot move out of `*u.d` which is behind a raw pointer
|
||||
--> $DIR/move-from-union-field-issue-66500.rs:26:5
|
||||
|
|
||||
LL | *u.d
|
||||
| ^^^^ move occurs because `*u.d` has type `std::string::String`, which does not implement the `Copy` trait
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
Loading…
Reference in New Issue
Block a user