Skip to content

Commit

Permalink
bug: nesting pattern types in enums doesn't use layout optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jan 22, 2024
1 parent 95aecb1 commit 6f77f02
Show file tree
Hide file tree
Showing 5 changed files with 360 additions and 6 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2135,7 +2135,7 @@ pub enum TyKind {
Err,
/// Placeholder for a `va_list`.
CVarArgs,
/// Pattern types like `u32 as 1..=`, which is the same as `NonZeroU32`,
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZeroU32`,
/// just as part of the type system.
Pat(P<Ty>, P<Pat>),
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2621,7 +2621,7 @@ pub enum TyKind<'hir> {
Infer,
/// Placeholder for a type that has failed to be defined.
Err(rustc_span::ErrorGuaranteed),
/// Pattern types (`u32 as 1..`)
/// Pattern types (`pattern_type!(u32 is 1..)`)
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/type/pattern_types/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#![allow(incomplete_features)]

// Check that pattern types do not affect existing macros.
// They don't, because `is` was never legal after `ty` fragments.
// They don't, because pattern types don't have surface syntax.

macro_rules! foo {
($t:ty is $p:pat) => {}; //~ ERROR `$t:ty` is followed by `is`, which is not allowed for `ty` fragments
Expand Down
18 changes: 15 additions & 3 deletions tests/ui/type/pattern_types/range_patterns.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
#![feature(pattern_types)]
#![feature(pattern_types, rustc_attrs)]
#![feature(core_pattern_type)]
#![feature(core_pattern_types)]
#![allow(incomplete_features)]

// check-pass
use std::pat::pattern_type;

#[rustc_layout(debug)]
type X = std::num::NonZeroU32; //~ ERROR layout_of
#[rustc_layout(debug)]
type Y = pattern_type!(u32 is 1..); //~ ERROR layout_of
#[rustc_layout(debug)]
type Z = Option<pattern_type!(u32 is 1..)>; //~ ERROR layout_of
#[rustc_layout(debug)]
type A = Option<std::num::NonZeroU32>; //~ ERROR layout_of
#[rustc_layout(debug)]
struct NonZeroU32New(pattern_type!(u32 is 1..)); //~ ERROR layout_of

fn main() {
let x: std::pat::pattern_type!(u32 is 1..) = todo!();
let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(42_u32) };
}
342 changes: 342 additions & 0 deletions tests/ui/type/pattern_types/range_patterns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
error: layout_of(NonZeroU32) = Layout {
size: Size(4 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: Align(8 bytes),
},
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 1..=4294967295,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
],
memory_index: [
0,
],
},
largest_niche: Some(
Niche {
offset: Size(0 bytes),
value: Int(
I32,
false,
),
valid_range: 1..=4294967295,
},
),
variants: Single {
index: 0,
},
max_repr_align: None,
unadjusted_abi_align: Align(4 bytes),
}
--> $DIR/range_patterns.rs:9:1
|
LL | type X = std::num::NonZeroU32;
| ^^^^^^

error: layout_of((u32) is 1..=) = Layout {
size: Size(4 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: Align(4 bytes),
},
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 1..=4294967295,
},
),
fields: Primitive,
largest_niche: None,
variants: Single {
index: 0,
},
max_repr_align: None,
unadjusted_abi_align: Align(4 bytes),
}
--> $DIR/range_patterns.rs:11:1
|
LL | type Y = pattern_type!(u32 is 1..);
| ^^^^^^

error: layout_of(Option<(u32) is 1..=>) = Layout {
size: Size(8 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: Align(8 bytes),
},
abi: ScalarPair(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=1,
},
Union {
value: Int(
I32,
false,
),
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
],
memory_index: [
0,
],
},
largest_niche: Some(
Niche {
offset: Size(0 bytes),
value: Int(
I32,
false,
),
valid_range: 0..=1,
},
),
variants: Multiple {
tag: Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=1,
},
tag_encoding: Direct,
tag_field: 0,
variants: [
Layout {
size: Size(4 bytes),
align: AbiAndPrefAlign {
abi: Align(1 bytes),
pref: Align(8 bytes),
},
abi: Aggregate {
sized: true,
},
fields: Arbitrary {
offsets: [],
memory_index: [],
},
largest_niche: None,
variants: Single {
index: 0,
},
max_repr_align: None,
unadjusted_abi_align: Align(1 bytes),
},
Layout {
size: Size(8 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: Align(8 bytes),
},
abi: ScalarPair(
Initialized {
value: Int(
I32,
false,
),
valid_range: 0..=1,
},
Union {
value: Int(
I32,
false,
),
},
),
fields: Arbitrary {
offsets: [
Size(4 bytes),
],
memory_index: [
0,
],
},
largest_niche: None,
variants: Single {
index: 1,
},
max_repr_align: None,
unadjusted_abi_align: Align(4 bytes),
},
],
},
max_repr_align: None,
unadjusted_abi_align: Align(4 bytes),
}
--> $DIR/range_patterns.rs:13:1
|
LL | type Z = Option<pattern_type!(u32 is 1..)>;
| ^^^^^^

error: layout_of(Option<NonZeroU32>) = Layout {
size: Size(4 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: Align(8 bytes),
},
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: (..=0) | (1..),
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
],
memory_index: [
0,
],
},
largest_niche: None,
variants: Multiple {
tag: Initialized {
value: Int(
I32,
false,
),
valid_range: (..=0) | (1..),
},
tag_encoding: Niche {
untagged_variant: 1,
niche_variants: 0..=0,
niche_start: 0,
},
tag_field: 0,
variants: [
Layout {
size: Size(0 bytes),
align: AbiAndPrefAlign {
abi: Align(1 bytes),
pref: Align(8 bytes),
},
abi: Aggregate {
sized: true,
},
fields: Arbitrary {
offsets: [],
memory_index: [],
},
largest_niche: None,
variants: Single {
index: 0,
},
max_repr_align: None,
unadjusted_abi_align: Align(1 bytes),
},
Layout {
size: Size(4 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: Align(8 bytes),
},
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 1..=4294967295,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
],
memory_index: [
0,
],
},
largest_niche: Some(
Niche {
offset: Size(0 bytes),
value: Int(
I32,
false,
),
valid_range: 1..=4294967295,
},
),
variants: Single {
index: 1,
},
max_repr_align: None,
unadjusted_abi_align: Align(4 bytes),
},
],
},
max_repr_align: None,
unadjusted_abi_align: Align(4 bytes),
}
--> $DIR/range_patterns.rs:15:1
|
LL | type A = Option<std::num::NonZeroU32>;
| ^^^^^^

error: layout_of(NonZeroU32New) = Layout {
size: Size(4 bytes),
align: AbiAndPrefAlign {
abi: Align(4 bytes),
pref: Align(8 bytes),
},
abi: Scalar(
Initialized {
value: Int(
I32,
false,
),
valid_range: 1..=4294967295,
},
),
fields: Arbitrary {
offsets: [
Size(0 bytes),
],
memory_index: [
0,
],
},
largest_niche: Some(
Niche {
offset: Size(0 bytes),
value: Int(
I32,
false,
),
valid_range: 1..=4294967295,
},
),
variants: Single {
index: 0,
},
max_repr_align: None,
unadjusted_abi_align: Align(4 bytes),
}
--> $DIR/range_patterns.rs:17:1
|
LL | struct NonZeroU32New(pattern_type!(u32 is 1..));
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 5 previous errors

0 comments on commit 6f77f02

Please sign in to comment.