Reject wrapping ranges of pattern types
This commit is contained in:
parent
f38819ce17
commit
916f9552e9
3 changed files with 41 additions and 106 deletions
|
@ -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(),
|
||||
|
|
|
@ -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) };
|
||||
|
|
|
@ -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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue