From 6f77f02fa68300716c0235c5740c21ab35ec436f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 2 Feb 2023 17:37:01 +0000 Subject: [PATCH] bug: nesting pattern types in enums doesn't use layout optimizations --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- tests/ui/type/pattern_types/macros.rs | 2 +- tests/ui/type/pattern_types/range_patterns.rs | 18 +- .../type/pattern_types/range_patterns.stderr | 342 ++++++++++++++++++ 5 files changed, 360 insertions(+), 6 deletions(-) create mode 100644 tests/ui/type/pattern_types/range_patterns.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f7f76a96b1b31..84cf987bf9ff0 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -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, P), } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f3ca233141ac2..8d2472f9ad0ac 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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>), } diff --git a/tests/ui/type/pattern_types/macros.rs b/tests/ui/type/pattern_types/macros.rs index 2d90142322d9d..a66e9a908791d 100644 --- a/tests/ui/type/pattern_types/macros.rs +++ b/tests/ui/type/pattern_types/macros.rs @@ -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 diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index 5f5a614faf55f..dc58b59650864 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -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; //~ ERROR layout_of +#[rustc_layout(debug)] +type A = Option; //~ 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) }; } diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr new file mode 100644 index 0000000000000..2231b96bba88e --- /dev/null +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -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; + | ^^^^^^ + +error: layout_of(Option) = 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; + | ^^^^^^ + +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 +