about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2025-07-23 22:13:05 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2025-07-24 10:18:37 -0700
commit01524abb05a4a60d0015972811b8bbb9bd2a73d3 (patch)
treeab184111d99dfdb1fb3c37482ce4d0b2f304d63d
parenta7a1618e6c835f1f00940ad72203d05808209a0d (diff)
downloadrust-01524abb05a4a60d0015972811b8bbb9bd2a73d3.tar.gz
rust-01524abb05a4a60d0015972811b8bbb9bd2a73d3.zip
MIR-build: No longer emit assumes in enum-as casting
This just uses the `valid_range` from the backend, so it's duplicating the range metadata that now we include on parameters and loads.

-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs80
-rw-r--r--tests/crashes/121097.rs10
-rw-r--r--tests/mir-opt/building/enum_cast.bar.built.after.mir5
-rw-r--r--tests/mir-opt/building/enum_cast.boo.built.after.mir5
-rw-r--r--tests/mir-opt/building/enum_cast.far.built.after.mir5
-rw-r--r--tests/mir-opt/building/enum_cast.offsetty.built.after.mir9
-rw-r--r--tests/mir-opt/building/enum_cast.rs7
-rw-r--r--tests/mir-opt/building/enum_cast.signy.built.after.mir9
-rw-r--r--tests/ui/simd/repr-simd-on-enum.rs15
-rw-r--r--tests/ui/simd/repr-simd-on-enum.stderr14
-rw-r--r--tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr30
11 files changed, 38 insertions, 151 deletions
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index daf8fa5f19e..a4ef6e92739 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -1,6 +1,6 @@
 //! See docs in `build/expr/mod.rs`.
 
-use rustc_abi::{BackendRepr, FieldIdx, Primitive};
+use rustc_abi::FieldIdx;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::bug;
@@ -9,7 +9,6 @@ use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::cast::{CastTy, mir_cast_kind};
-use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, Ty, UpvarArgs};
 use rustc_span::source_map::Spanned;
@@ -200,8 +199,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 {
                     let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx);
                     let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not));
-                    let layout =
-                        this.tcx.layout_of(this.typing_env().as_query_input(source_expr.ty));
                     let discr = this.temp(discr_ty, source_expr.span);
                     this.cfg.push_assign(
                         block,
@@ -209,80 +206,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         discr,
                         Rvalue::Discriminant(temp.into()),
                     );
-                    let (op, ty) = (Operand::Move(discr), discr_ty);
-
-                    if let BackendRepr::Scalar(scalar) = layout.unwrap().backend_repr
-                        && !scalar.is_always_valid(&this.tcx)
-                        && let Primitive::Int(int_width, _signed) = scalar.primitive()
-                    {
-                        let unsigned_ty = int_width.to_ty(this.tcx, false);
-                        let unsigned_place = this.temp(unsigned_ty, expr_span);
-                        this.cfg.push_assign(
-                            block,
-                            source_info,
-                            unsigned_place,
-                            Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr), unsigned_ty),
-                        );
-
-                        let bool_ty = this.tcx.types.bool;
-                        let range = scalar.valid_range(&this.tcx);
-                        let merge_op =
-                            if range.start <= range.end { BinOp::BitAnd } else { BinOp::BitOr };
-
-                        let mut comparer = |range: u128, bin_op: BinOp| -> Place<'tcx> {
-                            // We can use `ty::TypingEnv::fully_monomorphized()` here
-                            // as we only need it to compute the layout of a primitive.
-                            let range_val = Const::from_bits(
-                                this.tcx,
-                                range,
-                                ty::TypingEnv::fully_monomorphized(),
-                                unsigned_ty,
-                            );
-                            let lit_op = this.literal_operand(expr.span, range_val);
-                            let is_bin_op = this.temp(bool_ty, expr_span);
-                            this.cfg.push_assign(
-                                block,
-                                source_info,
-                                is_bin_op,
-                                Rvalue::BinaryOp(
-                                    bin_op,
-                                    Box::new((Operand::Copy(unsigned_place), lit_op)),
-                                ),
-                            );
-                            is_bin_op
-                        };
-                        let assert_place = if range.start == 0 {
-                            comparer(range.end, BinOp::Le)
-                        } else {
-                            let start_place = comparer(range.start, BinOp::Ge);
-                            let end_place = comparer(range.end, BinOp::Le);
-                            let merge_place = this.temp(bool_ty, expr_span);
-                            this.cfg.push_assign(
-                                block,
-                                source_info,
-                                merge_place,
-                                Rvalue::BinaryOp(
-                                    merge_op,
-                                    Box::new((
-                                        Operand::Move(start_place),
-                                        Operand::Move(end_place),
-                                    )),
-                                ),
-                            );
-                            merge_place
-                        };
-                        this.cfg.push(
-                            block,
-                            Statement::new(
-                                source_info,
-                                StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(
-                                    Operand::Move(assert_place),
-                                ))),
-                            ),
-                        );
-                    }
-
-                    (op, ty)
+                    (Operand::Move(discr), discr_ty)
                 } else {
                     let ty = source_expr.ty;
                     let source = unpack!(
diff --git a/tests/crashes/121097.rs b/tests/crashes/121097.rs
deleted file mode 100644
index 65c6028e03e..00000000000
--- a/tests/crashes/121097.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #121097
-#[repr(simd)]
-enum Aligned {
-    Zero = 0,
-    One = 1,
-}
-
-fn tou8(al: Aligned) -> u8 {
-    al as u8
-}
diff --git a/tests/mir-opt/building/enum_cast.bar.built.after.mir b/tests/mir-opt/building/enum_cast.bar.built.after.mir
index 72d0cf5d1e8..0dc6448ffad 100644
--- a/tests/mir-opt/building/enum_cast.bar.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.bar.built.after.mir
@@ -5,16 +5,11 @@ fn bar(_1: Bar) -> usize {
     let mut _0: usize;
     let _2: Bar;
     let mut _3: isize;
-    let mut _4: u8;
-    let mut _5: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = move _1;
         _3 = discriminant(_2);
-        _4 = copy _3 as u8 (IntToInt);
-        _5 = Le(copy _4, const 1_u8);
-        assume(move _5);
         _0 = move _3 as usize (IntToInt);
         StorageDead(_2);
         return;
diff --git a/tests/mir-opt/building/enum_cast.boo.built.after.mir b/tests/mir-opt/building/enum_cast.boo.built.after.mir
index 91e06dc8862..3540a2b1e2e 100644
--- a/tests/mir-opt/building/enum_cast.boo.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.boo.built.after.mir
@@ -5,16 +5,11 @@ fn boo(_1: Boo) -> usize {
     let mut _0: usize;
     let _2: Boo;
     let mut _3: u8;
-    let mut _4: u8;
-    let mut _5: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = move _1;
         _3 = discriminant(_2);
-        _4 = copy _3 as u8 (IntToInt);
-        _5 = Le(copy _4, const 1_u8);
-        assume(move _5);
         _0 = move _3 as usize (IntToInt);
         StorageDead(_2);
         return;
diff --git a/tests/mir-opt/building/enum_cast.far.built.after.mir b/tests/mir-opt/building/enum_cast.far.built.after.mir
index 14eaf344190..da34b7ba6c2 100644
--- a/tests/mir-opt/building/enum_cast.far.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.far.built.after.mir
@@ -5,16 +5,11 @@ fn far(_1: Far) -> isize {
     let mut _0: isize;
     let _2: Far;
     let mut _3: i16;
-    let mut _4: u16;
-    let mut _5: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = move _1;
         _3 = discriminant(_2);
-        _4 = copy _3 as u16 (IntToInt);
-        _5 = Le(copy _4, const 1_u16);
-        assume(move _5);
         _0 = move _3 as isize (IntToInt);
         StorageDead(_2);
         return;
diff --git a/tests/mir-opt/building/enum_cast.offsetty.built.after.mir b/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
index 1c2acbe3023..b84ce0de9a0 100644
--- a/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
@@ -5,20 +5,11 @@ fn offsetty(_1: NotStartingAtZero) -> u32 {
     let mut _0: u32;
     let _2: NotStartingAtZero;
     let mut _3: isize;
-    let mut _4: u8;
-    let mut _5: bool;
-    let mut _6: bool;
-    let mut _7: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = move _1;
         _3 = discriminant(_2);
-        _4 = copy _3 as u8 (IntToInt);
-        _5 = Ge(copy _4, const 4_u8);
-        _6 = Le(copy _4, const 8_u8);
-        _7 = BitAnd(move _5, move _6);
-        assume(move _7);
         _0 = move _3 as u32 (IntToInt);
         StorageDead(_2);
         return;
diff --git a/tests/mir-opt/building/enum_cast.rs b/tests/mir-opt/building/enum_cast.rs
index 4fb9a27e309..eaf5537e0ab 100644
--- a/tests/mir-opt/building/enum_cast.rs
+++ b/tests/mir-opt/building/enum_cast.rs
@@ -4,6 +4,13 @@
 // EMIT_MIR enum_cast.boo.built.after.mir
 // EMIT_MIR enum_cast.far.built.after.mir
 
+// Previously MIR building included range `Assume`s in the MIR statements,
+// which these tests demonstrated, but now that we have range metadata on
+// parameters in LLVM (in addition to !range metadata on loads) the impact
+// of the extra volume of MIR is worse than its value.
+// Thus these are now about the discriminant type and the cast type,
+// both of which might be different from the backend type of the tag.
+
 enum Foo {
     A,
 }
diff --git a/tests/mir-opt/building/enum_cast.signy.built.after.mir b/tests/mir-opt/building/enum_cast.signy.built.after.mir
index 39b6dfaf005..503c506748f 100644
--- a/tests/mir-opt/building/enum_cast.signy.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.signy.built.after.mir
@@ -5,20 +5,11 @@ fn signy(_1: SignedAroundZero) -> i16 {
     let mut _0: i16;
     let _2: SignedAroundZero;
     let mut _3: i16;
-    let mut _4: u16;
-    let mut _5: bool;
-    let mut _6: bool;
-    let mut _7: bool;
 
     bb0: {
         StorageLive(_2);
         _2 = move _1;
         _3 = discriminant(_2);
-        _4 = copy _3 as u16 (IntToInt);
-        _5 = Ge(copy _4, const 65534_u16);
-        _6 = Le(copy _4, const 2_u16);
-        _7 = BitOr(move _5, move _6);
-        assume(move _7);
         _0 = move _3 as i16 (IntToInt);
         StorageDead(_2);
         return;
diff --git a/tests/ui/simd/repr-simd-on-enum.rs b/tests/ui/simd/repr-simd-on-enum.rs
new file mode 100644
index 00000000000..49cf9e92d36
--- /dev/null
+++ b/tests/ui/simd/repr-simd-on-enum.rs
@@ -0,0 +1,15 @@
+// Used to ICE; see <https://github.com/rust-lang/rust/issues/121097>
+
+#![feature(repr_simd)]
+
+#[repr(simd)] //~ ERROR attribute should be applied to a struct
+enum Aligned {
+    Zero = 0,
+    One = 1,
+}
+
+fn tou8(al: Aligned) -> u8 {
+    al as u8
+}
+
+fn main() {}
diff --git a/tests/ui/simd/repr-simd-on-enum.stderr b/tests/ui/simd/repr-simd-on-enum.stderr
new file mode 100644
index 00000000000..6a19a16e8ea
--- /dev/null
+++ b/tests/ui/simd/repr-simd-on-enum.stderr
@@ -0,0 +1,14 @@
+error[E0517]: attribute should be applied to a struct
+  --> $DIR/repr-simd-on-enum.rs:5:8
+   |
+LL |   #[repr(simd)]
+   |          ^^^^
+LL | / enum Aligned {
+LL | |     Zero = 0,
+LL | |     One = 1,
+LL | | }
+   | |_- not a struct
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0517`.
diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
index 084008d8b2a..13ae6dfcaa3 100644
--- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
+++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -9,36 +9,6 @@ note: ...which requires const-evaluating + checking `Alpha::V3::{constant#0}`...
    |
 LL |     V3 = Self::V1 {} as u8 + 2,
    |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires caching mir of `Alpha::V3::{constant#0}` for CTFE...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires elaborating drops for `Alpha::V3::{constant#0}`...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires borrow-checking `Alpha::V3::{constant#0}`...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `Alpha::V3::{constant#0}`...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const checking `Alpha::V3::{constant#0}`...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `Alpha::V3::{constant#0}`...
-  --> $DIR/self-in-enum-definition.rs:5:10
-   |
-LL |     V3 = Self::V1 {} as u8 + 2,
-   |          ^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Alpha`...
    = note: ...which again requires simplifying constant for the type system `Alpha::V3::{constant#0}`, completing the cycle
 note: cycle used when checking that `Alpha` is well-formed