Auto merge of #90373 - tmiasko:union-qualification, r=oli-obk
Use type based qualification for unions
Union field access is currently qualified based on the qualification of
a value previously assigned to the union. At the same time, every union
access transmutes the content of the union, which might result in a
different qualification.
For example, consider constants A and B as defined below, under the
current rules neither contains interior mutability, since a value used
in the initial assignment did not contain `UnsafeCell` constructor.
```rust
#![feature(untagged_unions)]
union U { i: u32, c: std::cell::Cell<u32> }
const A: U = U { i: 0 };
const B: std::cell::Cell<u32> = unsafe { U { i: 0 }.c };
```
To avoid the issue, the changes here propose to consider the content of
a union as opaque and use type based qualification for union types.
Fixes #90268.
`@rust-lang/wg-const-eval`
This commit is contained in:
@@ -258,6 +258,9 @@ where
|
||||
if Q::in_adt_inherently(cx, def, substs) {
|
||||
return true;
|
||||
}
|
||||
if def.is_union() && Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, proceed structurally...
|
||||
|
||||
@@ -47,9 +47,19 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn assign_qualif_direct(&mut self, place: &mir::Place<'tcx>, value: bool) {
|
||||
fn assign_qualif_direct(&mut self, place: &mir::Place<'tcx>, mut value: bool) {
|
||||
debug_assert!(!place.is_indirect());
|
||||
|
||||
if !value {
|
||||
for (base, _elem) in place.iter_projections() {
|
||||
let base_ty = base.ty(self.ccx.body, self.ccx.tcx);
|
||||
if base_ty.ty.is_union() && Q::in_any_value_of_ty(self.ccx, base_ty.ty) {
|
||||
value = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match (value, place.as_ref()) {
|
||||
(true, mir::PlaceRef { local, .. }) => {
|
||||
self.state.qualif.insert(local);
|
||||
|
||||
Reference in New Issue
Block a user