mirror of https://github.com/rust-lang/rust.git
Rollup merge of #125616 - RalfJung:mir-validate-downcast-projection, r=compiler-errors
MIR validation: ensure that downcast projection is followed by field projection Cc https://github.com/rust-lang/rust/issues/120369
This commit is contained in:
commit
61f9d35798
|
@ -1008,8 +1008,8 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
|
||||||
/// element:
|
/// element:
|
||||||
///
|
///
|
||||||
/// - [`Downcast`](ProjectionElem::Downcast): This projection sets the place's variant index to the
|
/// - [`Downcast`](ProjectionElem::Downcast): This projection sets the place's variant index to the
|
||||||
/// given one, and makes no other changes. A `Downcast` projection on a place with its variant
|
/// given one, and makes no other changes. A `Downcast` projection must always be followed
|
||||||
/// index already set is not well-formed.
|
/// immediately by a `Field` projection.
|
||||||
/// - [`Field`](ProjectionElem::Field): `Field` projections take their parent place and create a
|
/// - [`Field`](ProjectionElem::Field): `Field` projections take their parent place and create a
|
||||||
/// place referring to one of the fields of the type. The resulting address is the parent
|
/// place referring to one of the fields of the type. The resulting address is the parent
|
||||||
/// address, plus the offset of the field. The type becomes the type of the field. If the parent
|
/// address, plus the offset of the field. The type becomes the type of the field. If the parent
|
||||||
|
|
|
@ -689,8 +689,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
if Some(adt_def.did()) == self.tcx.lang_items().dyn_metadata() {
|
if Some(adt_def.did()) == self.tcx.lang_items().dyn_metadata() {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!("You can't project to field {f:?} of `DynMetadata` because \
|
format!(
|
||||||
layout is weird and thinks it doesn't have fields."),
|
"You can't project to field {f:?} of `DynMetadata` because \
|
||||||
|
layout is weird and thinks it doesn't have fields."
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,7 +841,25 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
&& cntxt != PlaceContext::NonUse(NonUseContext::VarDebugInfo)
|
&& cntxt != PlaceContext::NonUse(NonUseContext::VarDebugInfo)
|
||||||
&& place.projection[1..].contains(&ProjectionElem::Deref)
|
&& place.projection[1..].contains(&ProjectionElem::Deref)
|
||||||
{
|
{
|
||||||
self.fail(location, format!("{place:?}, has deref at the wrong place"));
|
self.fail(
|
||||||
|
location,
|
||||||
|
format!("place {place:?} has deref as a later projection (it is only permitted as the first projection)"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure all downcast projections are followed by field projections.
|
||||||
|
let mut projections_iter = place.projection.iter();
|
||||||
|
while let Some(proj) = projections_iter.next() {
|
||||||
|
if matches!(proj, ProjectionElem::Downcast(..)) {
|
||||||
|
if !matches!(projections_iter.next(), Some(ProjectionElem::Field(..))) {
|
||||||
|
self.fail(
|
||||||
|
location,
|
||||||
|
format!(
|
||||||
|
"place {place:?} has `Downcast` projection not followed by `Field`"
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.super_place(place, cntxt, location);
|
self.super_place(place, cntxt, location);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC:
|
thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC:
|
||||||
broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]:
|
broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]:
|
||||||
(*(_2.0: *mut i32)), has deref at the wrong place
|
place (*(_2.0: *mut i32)) has deref as a later projection (it is only permitted as the first projection)
|
||||||
stack backtrace:
|
stack backtrace:
|
||||||
|
|
||||||
error: the compiler unexpectedly panicked. this is a bug.
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
Loading…
Reference in New Issue