Skip to content

Commit 25b70b3

Browse files
committed
const prop nonsense eliminated
1 parent 99c1305 commit 25b70b3

File tree

6 files changed

+32
-58
lines changed

6 files changed

+32
-58
lines changed

compiler/rustc_const_eval/src/errors.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -860,9 +860,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
860860
InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {
861861
rustc_middle::error::middle_adjust_for_foreign_abi_error
862862
}
863-
InvalidProgramInfo::ConstPropNonsense => {
864-
panic!("We had const-prop nonsense, this should never be printed")
865-
}
866863
}
867864
}
868865
fn add_args<G: EmissionGuarantee>(
@@ -871,9 +868,7 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
871868
builder: &mut DiagnosticBuilder<'_, G>,
872869
) {
873870
match self {
874-
InvalidProgramInfo::TooGeneric
875-
| InvalidProgramInfo::AlreadyReported(_)
876-
| InvalidProgramInfo::ConstPropNonsense => {}
871+
InvalidProgramInfo::TooGeneric | InvalidProgramInfo::AlreadyReported(_) => {}
877872
InvalidProgramInfo::Layout(e) => {
878873
// The level doesn't matter, `diag` is consumed without it being used.
879874
let dummy_level = Level::Bug;

compiler/rustc_const_eval/src/interpret/operand.rs

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

compiler/rustc_const_eval/src/interpret/place.rs

+3-16
Original file line numberDiff line numberDiff line change
@@ -519,11 +519,7 @@ where
519519
} else {
520520
// Unsized `Local` isn't okay (we cannot store the metadata).
521521
match frame_ref.locals[local].access()? {
522-
Operand::Immediate(_) => {
523-
// ConstProp marks *all* locals as `Immediate::Uninit` since it cannot
524-
// efficiently check whether they are sized. We have to catch that case here.
525-
throw_inval!(ConstPropNonsense);
526-
}
522+
Operand::Immediate(_) => bug!(),
527523
Operand::Indirect(mplace) => Place::Ptr(*mplace),
528524
}
529525
};
@@ -816,17 +812,8 @@ where
816812
// avoid force_allocation.
817813
let src = match self.read_immediate_raw(src)? {
818814
Right(src_val) => {
819-
// FIXME(const_prop): Const-prop can possibly evaluate an
820-
// unsized copy operation when it thinks that the type is
821-
// actually sized, due to a trivially false where-clause
822-
// predicate like `where Self: Sized` with `Self = dyn Trait`.
823-
// See #102553 for an example of such a predicate.
824-
if src.layout().is_unsized() {
825-
throw_inval!(ConstPropNonsense);
826-
}
827-
if dest.layout().is_unsized() {
828-
throw_inval!(ConstPropNonsense);
829-
}
815+
assert!(!src.layout().is_unsized());
816+
assert!(!dest.layout().is_unsized());
830817
assert_eq!(src.layout().size, dest.layout().size);
831818
// Yay, we got a value that we can write directly.
832819
return if layout_compat {

compiler/rustc_const_eval/src/interpret/projection.rs

+21-28
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,7 @@ where
153153

154154
// Offset may need adjustment for unsized fields.
155155
let (meta, offset) = if field_layout.is_unsized() {
156-
if base.layout().is_sized() {
157-
// An unsized field of a sized type? Sure...
158-
// But const-prop actually feeds us such nonsense MIR! (see test `const_prop/issue-86351.rs`)
159-
throw_inval!(ConstPropNonsense);
160-
}
156+
assert!(!base.layout().is_sized());
161157
let base_meta = base.meta();
162158
// Re-use parent metadata to determine dynamic field layout.
163159
// With custom DSTS, this *will* execute user-defined code, but the same
@@ -205,29 +201,26 @@ where
205201
// see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.)
206202
// So we just "offset" by 0.
207203
let layout = base.layout().for_variant(self, variant);
208-
if layout.abi.is_uninhabited() {
209-
// `read_discriminant` should have excluded uninhabited variants... but ConstProp calls
210-
// us on dead code.
211-
// In the future we might want to allow this to permit code like this:
212-
// (this is a Rust/MIR pseudocode mix)
213-
// ```
214-
// enum Option2 {
215-
// Some(i32, !),
216-
// None,
217-
// }
218-
//
219-
// fn panic() -> ! { panic!() }
220-
//
221-
// let x: Option2;
222-
// x.Some.0 = 42;
223-
// x.Some.1 = panic();
224-
// SetDiscriminant(x, Some);
225-
// ```
226-
// However, for now we don't generate such MIR, and this check here *has* found real
227-
// bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting
228-
// it.
229-
throw_inval!(ConstPropNonsense)
230-
}
204+
// In the future we might want to allow this to permit code like this:
205+
// (this is a Rust/MIR pseudocode mix)
206+
// ```
207+
// enum Option2 {
208+
// Some(i32, !),
209+
// None,
210+
// }
211+
//
212+
// fn panic() -> ! { panic!() }
213+
//
214+
// let x: Option2;
215+
// x.Some.0 = 42;
216+
// x.Some.1 = panic();
217+
// SetDiscriminant(x, Some);
218+
// ```
219+
// However, for now we don't generate such MIR, and this check here *has* found real
220+
// bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting
221+
// it.
222+
assert!(!layout.abi.is_uninhabited());
223+
231224
// This cannot be `transmute` as variants *can* have a smaller size than the entire enum.
232225
base.offset(Size::ZERO, layout, self)
233226
}

compiler/rustc_middle/src/mir/interpret/error.rs

-2
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,6 @@ pub enum InvalidProgramInfo<'tcx> {
208208
/// (which unfortunately typeck does not reject).
209209
/// Not using `FnAbiError` as that contains a nested `LayoutError`.
210210
FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
211-
/// We are runnning into a nonsense situation due to ConstProp violating our invariants.
212-
ConstPropNonsense,
213211
}
214212

215213
/// Details of why a pointer had to be in-bounds.

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,12 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
403403
operand,
404404
&mut |elem, op| match elem {
405405
TrackElem::Field(idx) => self.ecx.project_field(op, idx.as_usize()).ok(),
406-
TrackElem::Variant(idx) => self.ecx.project_downcast(op, idx).ok(),
406+
TrackElem::Variant(idx) => {
407+
if op.layout.for_variant(&self.ecx, idx).abi.is_uninhabited() {
408+
return None;
409+
}
410+
self.ecx.project_downcast(op, idx).ok()
411+
}
407412
TrackElem::Discriminant => {
408413
let variant = self.ecx.read_discriminant(op).ok()?;
409414
let discr_value =

0 commit comments

Comments
 (0)