mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
only emit error for ManuallyDrop derefs
This commit is contained in:
parent
44defaea3a
commit
97974e3cab
@ -244,14 +244,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let ty::Ref(region, _, mutbl) = method.sig.output().kind {
|
||||
*deref = OverloadedDeref { region, mutbl };
|
||||
}
|
||||
// If this is a union field, also throw an error.
|
||||
// Union fields should not get mutable auto-deref'd (see RFC 2514).
|
||||
if inside_union {
|
||||
// If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
|
||||
// This helps avoid accidental drops.
|
||||
if inside_union
|
||||
&& source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop())
|
||||
{
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
expr.span,
|
||||
"not automatically applying `DerefMut` on union field",
|
||||
"not automatically applying `DerefMut` on `ManuallyDrop` union field",
|
||||
);
|
||||
err.help(
|
||||
"writing to this reference calls the destructor for the old value",
|
||||
);
|
||||
err.help("writing to this field calls the destructor for the old value");
|
||||
err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor");
|
||||
err.emit();
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
// ignore-tidy-linelength
|
||||
//! Test the part of RFC 2514 that is about not applying `DerefMut` coercions
|
||||
//! of union fields.
|
||||
#![feature(untagged_unions)]
|
||||
@ -11,9 +12,9 @@ union U2<T> { x:(), f: (ManuallyDrop<(T,)>,) }
|
||||
fn main() {
|
||||
let mut u : U1<Vec<i32>> = U1 { x: () };
|
||||
unsafe { (*u.f).0 = Vec::new() }; // explicit deref, this compiles
|
||||
unsafe { u.f.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on union field
|
||||
unsafe { u.f.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
|
||||
|
||||
let mut u : U2<Vec<i32>> = U2 { x: () };
|
||||
unsafe { (*u.f.0).0 = Vec::new() }; // explicit deref, this compiles
|
||||
unsafe { u.f.0.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on union field
|
||||
unsafe { u.f.0.0 = Vec::new() }; //~ERROR not automatically applying `DerefMut` on `ManuallyDrop` union field
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
error: not automatically applying `DerefMut` on union field
|
||||
--> $DIR/union-deref.rs:14:14
|
||||
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
|
||||
--> $DIR/union-deref.rs:15:14
|
||||
|
|
||||
LL | unsafe { u.f.0 = Vec::new() };
|
||||
| ^^^
|
||||
|
|
||||
= help: writing to this field calls the destructor for the old value
|
||||
= help: writing to this reference calls the destructor for the old value
|
||||
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
|
||||
|
||||
error: not automatically applying `DerefMut` on union field
|
||||
--> $DIR/union-deref.rs:18:14
|
||||
error: not automatically applying `DerefMut` on `ManuallyDrop` union field
|
||||
--> $DIR/union-deref.rs:19:14
|
||||
|
|
||||
LL | unsafe { u.f.0.0 = Vec::new() };
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: writing to this field calls the destructor for the old value
|
||||
= help: writing to this reference calls the destructor for the old value
|
||||
= help: add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user