1
Fork 0

const prop nonsense eliminated

This commit is contained in:
Oli Scherer 2024-01-05 17:31:38 +00:00
parent 6ecb2aa580
commit 1f398abcb6
6 changed files with 32 additions and 58 deletions

View file

@ -860,9 +860,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => { InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {
rustc_middle::error::middle_adjust_for_foreign_abi_error rustc_middle::error::middle_adjust_for_foreign_abi_error
} }
InvalidProgramInfo::ConstPropNonsense => {
panic!("We had const-prop nonsense, this should never be printed")
}
} }
} }
fn add_args<G: EmissionGuarantee>( fn add_args<G: EmissionGuarantee>(
@ -871,9 +868,7 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
builder: &mut DiagnosticBuilder<'_, G>, builder: &mut DiagnosticBuilder<'_, G>,
) { ) {
match self { match self {
InvalidProgramInfo::TooGeneric InvalidProgramInfo::TooGeneric | InvalidProgramInfo::AlreadyReported(_) => {}
| InvalidProgramInfo::AlreadyReported(_)
| InvalidProgramInfo::ConstPropNonsense => {}
InvalidProgramInfo::Layout(e) => { InvalidProgramInfo::Layout(e) => {
// The level doesn't matter, `diag` is consumed without it being used. // The level doesn't matter, `diag` is consumed without it being used.
let dummy_level = Level::Bug; let dummy_level = Level::Bug;

View file

@ -643,11 +643,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let layout = self.layout_of_local(frame, local, layout)?; let layout = self.layout_of_local(frame, local, layout)?;
let op = *frame.locals[local].access()?; let op = *frame.locals[local].access()?;
if matches!(op, Operand::Immediate(_)) { if matches!(op, Operand::Immediate(_)) {
if layout.is_unsized() { assert!(!layout.is_unsized());
// ConstProp marks *all* locals as `Immediate::Uninit` since it cannot
// efficiently check whether they are sized. We have to catch that case here.
throw_inval!(ConstPropNonsense);
}
} }
Ok(OpTy { op, layout }) Ok(OpTy { op, layout })
} }

View file

@ -519,11 +519,7 @@ where
} else { } else {
// Unsized `Local` isn't okay (we cannot store the metadata). // Unsized `Local` isn't okay (we cannot store the metadata).
match frame_ref.locals[local].access()? { match frame_ref.locals[local].access()? {
Operand::Immediate(_) => { Operand::Immediate(_) => bug!(),
// ConstProp marks *all* locals as `Immediate::Uninit` since it cannot
// efficiently check whether they are sized. We have to catch that case here.
throw_inval!(ConstPropNonsense);
}
Operand::Indirect(mplace) => Place::Ptr(*mplace), Operand::Indirect(mplace) => Place::Ptr(*mplace),
} }
}; };
@ -816,17 +812,8 @@ where
// avoid force_allocation. // avoid force_allocation.
let src = match self.read_immediate_raw(src)? { let src = match self.read_immediate_raw(src)? {
Right(src_val) => { Right(src_val) => {
// FIXME(const_prop): Const-prop can possibly evaluate an assert!(!src.layout().is_unsized());
// unsized copy operation when it thinks that the type is assert!(!dest.layout().is_unsized());
// actually sized, due to a trivially false where-clause
// predicate like `where Self: Sized` with `Self = dyn Trait`.
// See #102553 for an example of such a predicate.
if src.layout().is_unsized() {
throw_inval!(ConstPropNonsense);
}
if dest.layout().is_unsized() {
throw_inval!(ConstPropNonsense);
}
assert_eq!(src.layout().size, dest.layout().size); assert_eq!(src.layout().size, dest.layout().size);
// Yay, we got a value that we can write directly. // Yay, we got a value that we can write directly.
return if layout_compat { return if layout_compat {

View file

@ -153,11 +153,7 @@ where
// Offset may need adjustment for unsized fields. // Offset may need adjustment for unsized fields.
let (meta, offset) = if field_layout.is_unsized() { let (meta, offset) = if field_layout.is_unsized() {
if base.layout().is_sized() { assert!(!base.layout().is_sized());
// An unsized field of a sized type? Sure...
// But const-prop actually feeds us such nonsense MIR! (see test `const_prop/issue-86351.rs`)
throw_inval!(ConstPropNonsense);
}
let base_meta = base.meta(); let base_meta = base.meta();
// Re-use parent metadata to determine dynamic field layout. // Re-use parent metadata to determine dynamic field layout.
// With custom DSTS, this *will* execute user-defined code, but the same // With custom DSTS, this *will* execute user-defined code, but the same
@ -205,9 +201,6 @@ where
// see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.) // see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.)
// So we just "offset" by 0. // So we just "offset" by 0.
let layout = base.layout().for_variant(self, variant); let layout = base.layout().for_variant(self, variant);
if layout.abi.is_uninhabited() {
// `read_discriminant` should have excluded uninhabited variants... but ConstProp calls
// us on dead code.
// In the future we might want to allow this to permit code like this: // In the future we might want to allow this to permit code like this:
// (this is a Rust/MIR pseudocode mix) // (this is a Rust/MIR pseudocode mix)
// ``` // ```
@ -226,8 +219,8 @@ where
// However, for now we don't generate such MIR, and this check here *has* found real // However, for now we don't generate such MIR, and this check here *has* found real
// bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting // bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting
// it. // it.
throw_inval!(ConstPropNonsense) assert!(!layout.abi.is_uninhabited());
}
// This cannot be `transmute` as variants *can* have a smaller size than the entire enum. // This cannot be `transmute` as variants *can* have a smaller size than the entire enum.
base.offset(Size::ZERO, layout, self) base.offset(Size::ZERO, layout, self)
} }

View file

@ -200,8 +200,6 @@ pub enum InvalidProgramInfo<'tcx> {
/// (which unfortunately typeck does not reject). /// (which unfortunately typeck does not reject).
/// Not using `FnAbiError` as that contains a nested `LayoutError`. /// Not using `FnAbiError` as that contains a nested `LayoutError`.
FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
/// We are runnning into a nonsense situation due to ConstProp violating our invariants.
ConstPropNonsense,
} }
/// Details of why a pointer had to be in-bounds. /// Details of why a pointer had to be in-bounds.

View file

@ -403,7 +403,12 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
operand, operand,
&mut |elem, op| match elem { &mut |elem, op| match elem {
TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).ok(), TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).ok(),
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(), TrackElem::Variant(idx) => {
if op.layout.for_variant(&self.ecx, idx).abi.is_uninhabited() {
return None;
}
self.ecx.project_downcast(op, idx).ok()
}
TrackElem::Discriminant => { TrackElem::Discriminant => {
let variant = self.ecx.read_discriminant(op).ok()?; let variant = self.ecx.read_discriminant(op).ok()?;
let discr_value = let discr_value =