summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs28
-rw-r--r--tests/ui/type/pattern_types/range_patterns.rs6
-rw-r--r--tests/ui/type/pattern_types/range_patterns.stderr113
3 files changed, 41 insertions, 106 deletions
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 5a4bb2c95da..7334beb52c9 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -220,6 +220,34 @@ fn layout_of_uncached<'tcx>(
                             .try_to_bits(tcx, cx.typing_env)
                             .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
 
+                        // FIXME(pattern_types): create implied bounds from pattern types in signatures
+                        // that require that the range end is >= the range start so that we can't hit
+                        // this error anymore without first having hit a trait solver error.
+                        // Very fuzzy on the details here, but pattern types are an internal impl detail,
+                        // so we can just go with this for now
+                        if scalar.is_signed() {
+                            let range = scalar.valid_range_mut();
+                            let start = layout.size.sign_extend(range.start);
+                            let end = layout.size.sign_extend(range.end);
+                            if end < start {
+                                let guar = tcx.dcx().err(format!(
+                                    "pattern type ranges cannot wrap: {start}..={end}"
+                                ));
+
+                                return Err(error(cx, LayoutError::ReferencesError(guar)));
+                            }
+                        } else {
+                            let range = scalar.valid_range_mut();
+                            if range.end < range.start {
+                                let guar = tcx.dcx().err(format!(
+                                    "pattern type ranges cannot wrap: {}..={}",
+                                    range.start, range.end
+                                ));
+
+                                return Err(error(cx, LayoutError::ReferencesError(guar)));
+                            }
+                        };
+
                         let niche = Niche {
                             offset: Size::ZERO,
                             value: scalar.primitive(),
diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs
index 3aa8426178a..dda7eb0ae4e 100644
--- a/tests/ui/type/pattern_types/range_patterns.rs
+++ b/tests/ui/type/pattern_types/range_patterns.rs
@@ -19,14 +19,14 @@ type A = Option<std::num::NonZeroU32>; //~ ERROR layout_of
 struct NonZeroU32New(pattern_type!(u32 is 1..)); //~ ERROR layout_of
 
 #[rustc_layout(debug)]
-type EMPTY = pattern_type!(u32 is 1..1); //~ ERROR layout_of
+type EMPTY = pattern_type!(u32 is 1..1); //~ ERROR unknown layout
 
 #[rustc_layout(debug)]
 type WRAP = pattern_type!(u32 is 1..0); //~ ERROR unknown layout
 //~^ ERROR: evaluation of constant value failed
 
 #[rustc_layout(debug)]
-type WRAP2 = pattern_type!(u32 is 5..2); //~ ERROR layout_of
+type WRAP2 = pattern_type!(u32 is 5..2); //~ ERROR unknown layout
 
 #[rustc_layout(debug)]
 type SIGN = pattern_type!(i8 is -10..=10); //~ ERROR layout_of
@@ -35,7 +35,7 @@ type SIGN = pattern_type!(i8 is -10..=10); //~ ERROR layout_of
 type MIN = pattern_type!(i8 is -128..=0); //~ ERROR layout_of
 
 #[rustc_layout(debug)]
-type SignedWrap = pattern_type!(i8 is 120..=-120); //~ ERROR layout_of
+type SignedWrap = pattern_type!(i8 is 120..=-120); //~ ERROR unknown layout
 
 fn main() {
     let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(42_u32) };
diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr
index b6abcf46224..a05995a33f9 100644
--- a/tests/ui/type/pattern_types/range_patterns.stderr
+++ b/tests/ui/type/pattern_types/range_patterns.stderr
@@ -357,40 +357,9 @@ error: layout_of(NonZeroU32New) = Layout {
 LL | struct NonZeroU32New(pattern_type!(u32 is 1..));
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: layout_of((u32) is 1..=0) = Layout {
-           size: Size(4 bytes),
-           align: AbiAndPrefAlign {
-               abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
-           },
-           backend_repr: Scalar(
-               Initialized {
-                   value: Int(
-                       I32,
-                       false,
-                   ),
-                   valid_range: (..=0) | (1..),
-               },
-           ),
-           fields: Primitive,
-           largest_niche: Some(
-               Niche {
-                   offset: Size(0 bytes),
-                   value: Int(
-                       I32,
-                       false,
-                   ),
-                   valid_range: (..=0) | (1..),
-               },
-           ),
-           uninhabited: false,
-           variants: Single {
-               index: 0,
-           },
-           max_repr_align: None,
-           unadjusted_abi_align: Align(4 bytes),
-           randomization_seed: $SEED,
-       }
+error: pattern type ranges cannot wrap: 1..=0
+
+error: the type has an unknown layout
   --> $DIR/range_patterns.rs:22:1
    |
 LL | type EMPTY = pattern_type!(u32 is 1..1);
@@ -408,40 +377,9 @@ error: the type has an unknown layout
 LL | type WRAP = pattern_type!(u32 is 1..0);
    | ^^^^^^^^^
 
-error: layout_of((u32) is 5..=1) = Layout {
-           size: Size(4 bytes),
-           align: AbiAndPrefAlign {
-               abi: Align(4 bytes),
-               pref: $SOME_ALIGN,
-           },
-           backend_repr: Scalar(
-               Initialized {
-                   value: Int(
-                       I32,
-                       false,
-                   ),
-                   valid_range: (..=1) | (5..),
-               },
-           ),
-           fields: Primitive,
-           largest_niche: Some(
-               Niche {
-                   offset: Size(0 bytes),
-                   value: Int(
-                       I32,
-                       false,
-                   ),
-                   valid_range: (..=1) | (5..),
-               },
-           ),
-           uninhabited: false,
-           variants: Single {
-               index: 0,
-           },
-           max_repr_align: None,
-           unadjusted_abi_align: Align(4 bytes),
-           randomization_seed: $SEED,
-       }
+error: pattern type ranges cannot wrap: 5..=1
+
+error: the type has an unknown layout
   --> $DIR/range_patterns.rs:29:1
    |
 LL | type WRAP2 = pattern_type!(u32 is 5..2);
@@ -525,45 +463,14 @@ error: layout_of((i8) is i8::MIN..=0) = Layout {
 LL | type MIN = pattern_type!(i8 is -128..=0);
    | ^^^^^^^^
 
-error: layout_of((i8) is 120..=-120) = Layout {
-           size: Size(1 bytes),
-           align: AbiAndPrefAlign {
-               abi: Align(1 bytes),
-               pref: $SOME_ALIGN,
-           },
-           backend_repr: Scalar(
-               Initialized {
-                   value: Int(
-                       I8,
-                       true,
-                   ),
-                   valid_range: 120..=136,
-               },
-           ),
-           fields: Primitive,
-           largest_niche: Some(
-               Niche {
-                   offset: Size(0 bytes),
-                   value: Int(
-                       I8,
-                       true,
-                   ),
-                   valid_range: 120..=136,
-               },
-           ),
-           uninhabited: false,
-           variants: Single {
-               index: 0,
-           },
-           max_repr_align: None,
-           unadjusted_abi_align: Align(1 bytes),
-           randomization_seed: $SEED,
-       }
+error: pattern type ranges cannot wrap: 120..=-120
+
+error: the type has an unknown layout
   --> $DIR/range_patterns.rs:38:1
    |
 LL | type SignedWrap = pattern_type!(i8 is 120..=-120);
    | ^^^^^^^^^^^^^^^
 
-error: aborting due to 12 previous errors
+error: aborting due to 15 previous errors
 
 For more information about this error, try `rustc --explain E0080`.