diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/enum | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
56 files changed, 1255 insertions, 0 deletions
diff --git a/src/test/ui/enum-discriminant/actually_not_an_enum-discriminant.rs b/src/test/ui/enum-discriminant/actually_not_an_enum-discriminant.rs new file mode 100644 index 000000000..6a566ab3a --- /dev/null +++ b/src/test/ui/enum-discriminant/actually_not_an_enum-discriminant.rs @@ -0,0 +1,49 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::discriminant_value; + +struct Zst; + +struct Struct { + _a: u32, +} + +union Union { + _a: u32, +} + +fn check(v: u8) { + assert_eq!(v, 0); +} + +pub fn generic<T>() +where + for<'a> T: Fn(&'a isize), +{ + let v: Vec<T> = Vec::new(); + let _: u8 = discriminant_value(&v); +} + +fn main() { + // check that we use `u8` as the discriminant value + // for everything that is not an enum. + check(discriminant_value(&true)); + check(discriminant_value(&'a')); + check(discriminant_value(&7)); + check(discriminant_value(&7.0)); + check(discriminant_value(&Zst)); + check(discriminant_value(&Struct { _a: 7 })); + check(discriminant_value(&Union { _a: 7 })); + check(discriminant_value(&[7, 77])); + check(discriminant_value(&(7 as *const ()))); + check(discriminant_value(&(7 as *mut ()))); + check(discriminant_value(&&7)); + check(discriminant_value(&&mut 7)); + check(discriminant_value(&check)); + let fn_ptr: fn(u8) = check; + check(discriminant_value(&fn_ptr)); + let hrtb: for<'a> fn(&'a str) -> &'a str = |x| x; + check(discriminant_value(&hrtb)); + check(discriminant_value(&(7, 77, 777))); +} diff --git a/src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs b/src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs new file mode 100644 index 000000000..4da7b5ab2 --- /dev/null +++ b/src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs @@ -0,0 +1,9 @@ +#![crate_type="lib"] +#![feature(arbitrary_enum_discriminant)] + +enum Enum { +//~^ ERROR `#[repr(inttype)]` must be specified + Unit = 1, + Tuple() = 2, + Struct{} = 3, +} diff --git a/src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr b/src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr new file mode 100644 index 000000000..803bb06fc --- /dev/null +++ b/src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr @@ -0,0 +1,9 @@ +error[E0732]: `#[repr(inttype)]` must be specified + --> $DIR/arbitrary_enum_discriminant-no-repr.rs:4:1 + | +LL | enum Enum { + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0732`. diff --git a/src/test/ui/enum-discriminant/arbitrary_enum_discriminant.rs b/src/test/ui/enum-discriminant/arbitrary_enum_discriminant.rs new file mode 100644 index 000000000..ccc423e4a --- /dev/null +++ b/src/test/ui/enum-discriminant/arbitrary_enum_discriminant.rs @@ -0,0 +1,43 @@ +// run-pass +#![feature(arbitrary_enum_discriminant, test)] + +extern crate test; + +use test::black_box; + +#[allow(dead_code)] +#[repr(u8)] +enum Enum { + Unit = 3, + Tuple(u16) = 2, + Struct { + a: u8, + b: u16, + } = 1, +} + +impl Enum { + const unsafe fn tag(&self) -> u8 { + *(self as *const Self as *const u8) + } +} + +fn main() { + const UNIT: Enum = Enum::Unit; + const TUPLE: Enum = Enum::Tuple(5); + const STRUCT: Enum = Enum::Struct{a: 7, b: 11}; + + // Ensure discriminants are correct during runtime execution + assert_eq!(3, unsafe { black_box(UNIT).tag() }); + assert_eq!(2, unsafe { black_box(TUPLE).tag() }); + assert_eq!(1, unsafe { black_box(STRUCT).tag() }); + + // Ensure discriminants are correct during CTFE + const UNIT_TAG: u8 = unsafe { UNIT.tag() }; + const TUPLE_TAG: u8 = unsafe { TUPLE.tag() }; + const STRUCT_TAG: u8 = unsafe { STRUCT.tag() }; + + assert_eq!(3, UNIT_TAG); + assert_eq!(2, TUPLE_TAG); + assert_eq!(1, STRUCT_TAG); +} diff --git a/src/test/ui/enum-discriminant/discriminant_size.rs b/src/test/ui/enum-discriminant/discriminant_size.rs new file mode 100644 index 000000000..b939a70df --- /dev/null +++ b/src/test/ui/enum-discriminant/discriminant_size.rs @@ -0,0 +1,54 @@ +// run-pass +#![feature(core_intrinsics, repr128)] +//~^ WARN the feature `repr128` is incomplete + +use std::intrinsics::discriminant_value; + +enum E1 { + A, + B, +} + +#[repr(i8)] +enum E2 { + A = 7, + B = -2, +} + +#[repr(C)] +enum E3 { + A = 42, + B = 100, +} + +#[repr(i128)] +enum E4 { + A = 0x1223_3445_5667_7889, + B = -0x1223_3445_5667_7889, +} + +fn main() { + let mut target: [isize; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E1::A); + assert_eq!(target, [0, 0, 0]); + target[1] = discriminant_value(&E1::B); + assert_eq!(target, [0, 1, 0]); + + let mut target: [i8; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E2::A); + assert_eq!(target, [0, 7, 0]); + target[1] = discriminant_value(&E2::B); + assert_eq!(target, [0, -2, 0]); + + let mut target: [isize; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E3::A); + assert_eq!(target, [0, 42, 0]); + target[1] = discriminant_value(&E3::B); + assert_eq!(target, [0, 100, 0]); + + let mut target: [i128; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E4::A); + assert_eq!(target, [0, 0x1223_3445_5667_7889, 0]); + target[1] = discriminant_value(&E4::B); + assert_eq!(target, [0, -0x1223_3445_5667_7889, 0]); +} diff --git a/src/test/ui/enum-discriminant/discriminant_size.stderr b/src/test/ui/enum-discriminant/discriminant_size.stderr new file mode 100644 index 000000000..efc7d9984 --- /dev/null +++ b/src/test/ui/enum-discriminant/discriminant_size.stderr @@ -0,0 +1,11 @@ +warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/discriminant_size.rs:2:29 + | +LL | #![feature(core_intrinsics, repr128)] + | ^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs new file mode 100644 index 000000000..8e162d5c4 --- /dev/null +++ b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(enum_intrinsics_non_enums)] + +use std::mem; + +#[allow(unused_tuple_struct_fields)] +enum ADT { + First(u32, u32), + Second(u64) +} + +pub fn main() { + assert!(mem::discriminant(&ADT::First(0,0)) == mem::discriminant(&ADT::First(1,1))); + assert!(mem::discriminant(&ADT::Second(5)) == mem::discriminant(&ADT::Second(6))); + assert!(mem::discriminant(&ADT::First(2,2)) != mem::discriminant(&ADT::Second(2))); + + let _ = mem::discriminant(&10); + let _ = mem::discriminant(&"test"); +} diff --git a/src/test/ui/enum-discriminant/discriminant_value.rs b/src/test/ui/enum-discriminant/discriminant_value.rs new file mode 100644 index 000000000..65ab411db --- /dev/null +++ b/src/test/ui/enum-discriminant/discriminant_value.rs @@ -0,0 +1,82 @@ +// run-pass +#![allow(stable_features)] +#![feature(arbitrary_enum_discriminant, core, core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +enum CLike1 { + A, + B, + C, + D +} + +enum CLike2 { + A = 5, + B = 2, + C = 19, + D +} + +#[repr(i8)] +enum CLike3 { + A = 5, + B, + C = -1, + D +} + +#[allow(unused_tuple_struct_fields)] +enum ADT { + First(u32, u32), + Second(u64) +} + +enum NullablePointer { + Something(#[allow(unused_tuple_struct_fields)] &'static u32), + Nothing +} + +static CONST : u32 = 0xBEEF; + +#[allow(dead_code)] +#[repr(isize)] +enum Mixed { + Unit = 3, + Tuple(u16) = 2, + Struct { + a: u8, + b: u16, + } = 1, +} + +pub fn main() { + assert_eq!(discriminant_value(&CLike1::A), 0isize); + assert_eq!(discriminant_value(&CLike1::B), 1); + assert_eq!(discriminant_value(&CLike1::C), 2); + assert_eq!(discriminant_value(&CLike1::D), 3); + + assert_eq!(discriminant_value(&CLike2::A), 5isize); + assert_eq!(discriminant_value(&CLike2::B), 2); + assert_eq!(discriminant_value(&CLike2::C), 19); + assert_eq!(discriminant_value(&CLike2::D), 20); + + assert_eq!(discriminant_value(&CLike3::A), 5i8); + assert_eq!(discriminant_value(&CLike3::B), 6); + assert_eq!(discriminant_value(&CLike3::C), -1); + assert_eq!(discriminant_value(&CLike3::D), 0); + + assert_eq!(discriminant_value(&ADT::First(0,0)), 0isize); + assert_eq!(discriminant_value(&ADT::Second(5)), 1); + + assert_eq!(discriminant_value(&NullablePointer::Nothing), 1isize); + assert_eq!(discriminant_value(&NullablePointer::Something(&CONST)), 0); + + assert_eq!(discriminant_value(&10), 0u8); + assert_eq!(discriminant_value(&"test"), 0u8); + + assert_eq!(discriminant_value(&Mixed::Unit), 3isize); + assert_eq!(discriminant_value(&Mixed::Tuple(5)), 2); + assert_eq!(discriminant_value(&Mixed::Struct{a: 7, b: 11}), 1); +} diff --git a/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs b/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs new file mode 100644 index 000000000..3e90af4d3 --- /dev/null +++ b/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs @@ -0,0 +1,10 @@ +#![crate_type="lib"] + +enum Enum { + Unit = 1, + //~^ ERROR custom discriminant values are not allowed in enums with tuple or struct variants + Tuple() = 2, + //~^ ERROR discriminants on non-unit variants are experimental + Struct{} = 3, + //~^ ERROR discriminants on non-unit variants are experimental +} diff --git a/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr b/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr new file mode 100644 index 000000000..b5f61e6e9 --- /dev/null +++ b/src/test/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.stderr @@ -0,0 +1,36 @@ +error[E0658]: discriminants on non-unit variants are experimental + --> $DIR/feature-gate-arbitrary_enum_discriminant.rs:6:13 + | +LL | Tuple() = 2, + | ^ + | + = note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable + +error[E0658]: discriminants on non-unit variants are experimental + --> $DIR/feature-gate-arbitrary_enum_discriminant.rs:8:14 + | +LL | Struct{} = 3, + | ^ + | + = note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable + +error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants + --> $DIR/feature-gate-arbitrary_enum_discriminant.rs:4:10 + | +LL | Unit = 1, + | ^ disallowed custom discriminant +LL | +LL | Tuple() = 2, + | ----------- tuple variant defined here +LL | +LL | Struct{} = 3, + | ------------ struct variant defined here + | + = note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information + = help: add `#![feature(arbitrary_enum_discriminant)]` to the crate attributes to enable + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs b/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs new file mode 100644 index 000000000..4760ca548 --- /dev/null +++ b/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs @@ -0,0 +1,14 @@ +#![feature(discriminant_kind)] + +use std::marker::DiscriminantKind; + +enum Uninhabited {} + +struct NewType; + +impl DiscriminantKind for NewType { + //~^ ERROR explicit impls for the `DiscriminantKind` trait are not permitted + type Discriminant = Uninhabited; +} + +fn main() {} diff --git a/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr b/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr new file mode 100644 index 000000000..38cfd13b9 --- /dev/null +++ b/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr @@ -0,0 +1,9 @@ +error[E0322]: explicit impls for the `DiscriminantKind` trait are not permitted + --> $DIR/forbidden-discriminant-kind-impl.rs:9:1 + | +LL | impl DiscriminantKind for NewType { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `DiscriminantKind` not allowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0322`. diff --git a/src/test/ui/enum-discriminant/issue-43398.rs b/src/test/ui/enum-discriminant/issue-43398.rs new file mode 100644 index 000000000..581db033f --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-43398.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(repr128)] +//~^ WARN the feature `repr128` is incomplete + +#[repr(i128)] +enum Big { A, B } + +fn main() { + println!("{} {:?}", + std::intrinsics::discriminant_value(&Big::A), + std::mem::discriminant(&Big::B)); +} diff --git a/src/test/ui/enum-discriminant/issue-43398.stderr b/src/test/ui/enum-discriminant/issue-43398.stderr new file mode 100644 index 000000000..9a394153b --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-43398.stderr @@ -0,0 +1,11 @@ +warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-43398.rs:4:12 + | +LL | #![feature(repr128)] + | ^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/enum-discriminant/issue-51582.rs b/src/test/ui/enum-discriminant/issue-51582.rs new file mode 100644 index 000000000..40a70c623 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-51582.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(core_intrinsics)] + +#[repr(i8)] +pub enum Enum { + VariantA, + VariantB, +} + +fn make_b() -> Enum { Enum::VariantB } + +fn main() { + assert_eq!(1, make_b() as i8); + assert_eq!(1, make_b() as u8); + assert_eq!(1, make_b() as i32); + assert_eq!(1, make_b() as u32); + assert_eq!(1, std::intrinsics::discriminant_value(&make_b())); +} diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs new file mode 100644 index 000000000..f927dd189 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs @@ -0,0 +1,16 @@ +#![feature(arbitrary_enum_discriminant, core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +#[repr(usize)] +enum MyWeirdOption<T> { + None = 0, + Some(T) = std::mem::size_of::<T>(), + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() { + assert_eq!(discriminant_value(&MyWeirdOption::<u8>::None), 0); + assert_eq!(discriminant_value(&MyWeirdOption::Some(0u8)), 1); +} diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr new file mode 100644 index 000000000..e4e10468d --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.stderr @@ -0,0 +1,11 @@ +error: generic parameters may not be used in const operations + --> $DIR/issue-70453-generics-in-discr-ice-2.rs:9:35 + | +LL | Some(T) = std::mem::size_of::<T>(), + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to previous error + diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs new file mode 100644 index 000000000..a0fb788a5 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs @@ -0,0 +1,17 @@ +#![feature(core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +#[repr(usize)] +enum MyWeirdOption<T> { +//~^ ERROR parameter `T` is never used + None = 0, + Some = std::mem::size_of::<T>(), + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() { + assert_eq!(discriminant_value(&MyWeirdOption::<u8>::None), 0); + assert_eq!(discriminant_value(&MyWeirdOption::<u8>::Some), 1); +} diff --git a/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr new file mode 100644 index 000000000..7ea8a3912 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70453-generics-in-discr-ice.stderr @@ -0,0 +1,21 @@ +error: generic parameters may not be used in const operations + --> $DIR/issue-70453-generics-in-discr-ice.rs:10:32 + | +LL | Some = std::mem::size_of::<T>(), + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error[E0392]: parameter `T` is never used + --> $DIR/issue-70453-generics-in-discr-ice.rs:7:20 + | +LL | enum MyWeirdOption<T> { + | ^ unused parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `T` to be a const parameter, use `const T: usize` instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs new file mode 100644 index 000000000..e62582fb5 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs @@ -0,0 +1,16 @@ +#![feature(arbitrary_enum_discriminant, core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +#[repr(usize)] +enum MyWeirdOption<T> { + None = 0, + Some(T) = core::mem::size_of::<*mut T>(), + //~^ ERROR generic parameters may not be used +} + +fn main() { + assert_eq!(discriminant_value(&MyWeirdOption::<()>::None), 0); + assert_eq!(discriminant_value(&MyWeirdOption::Some(())), core::mem::size_of::<usize>()); +} diff --git a/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr new file mode 100644 index 000000000..0a7a63160 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr @@ -0,0 +1,11 @@ +error: generic parameters may not be used in const operations + --> $DIR/issue-70453-polymorphic-ctfe.rs:9:41 + | +LL | Some(T) = core::mem::size_of::<*mut T>(), + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to previous error + diff --git a/src/test/ui/enum-discriminant/issue-70509-partial_eq.rs b/src/test/ui/enum-discriminant/issue-70509-partial_eq.rs new file mode 100644 index 000000000..ae389e114 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70509-partial_eq.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(repr128, arbitrary_enum_discriminant)] +//~^ WARN the feature `repr128` is incomplete + +#[derive(PartialEq, Debug)] +#[repr(i128)] +enum Test { + A(Box<u64>) = 0, + B(usize) = u64::MAX as i128 + 1, +} + +fn main() { + assert_ne!(Test::A(Box::new(2)), Test::B(0)); + // This previously caused a segfault. + // + // See https://github.com/rust-lang/rust/issues/70509#issuecomment-620654186 + // for a detailed explanation. +} diff --git a/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr b/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr new file mode 100644 index 000000000..5bf6ea56e --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr @@ -0,0 +1,11 @@ +warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-70509-partial_eq.rs:2:12 + | +LL | #![feature(repr128, arbitrary_enum_discriminant)] + | ^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/enum-discriminant/issue-90038.rs b/src/test/ui/enum-discriminant/issue-90038.rs new file mode 100644 index 000000000..5e98eccd9 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-90038.rs @@ -0,0 +1,21 @@ +// run-pass + +#[repr(u32)] +pub enum Foo { + // Greater than or equal to 2 + A = 2, +} + +pub enum Bar { + A(Foo), + // More than two const variants + B, + C, +} + +fn main() { + match Bar::A(Foo::A) { + Bar::A(_) => (), + _ => unreachable!(), + } +} diff --git a/src/test/ui/enum-discriminant/niche-prefer-zero.rs b/src/test/ui/enum-discriminant/niche-prefer-zero.rs new file mode 100644 index 000000000..f20607a89 --- /dev/null +++ b/src/test/ui/enum-discriminant/niche-prefer-zero.rs @@ -0,0 +1,14 @@ +// Check that niche selection prefers zero. +// See https://github.com/rust-lang/rust/pull/87794 +// run-pass +#[repr(u8)] +pub enum Size { + One = 1, + Two = 2, + Three = 3, +} + +fn main() { + // check that `None` is zero + assert_eq!(0, unsafe { std::mem::transmute::<Option<Size>, u8>(None) }); +} diff --git a/src/test/ui/enum-discriminant/niche.rs b/src/test/ui/enum-discriminant/niche.rs new file mode 100644 index 000000000..8d3061050 --- /dev/null +++ b/src/test/ui/enum-discriminant/niche.rs @@ -0,0 +1,109 @@ +// run-pass + +//! Make sure that we read and write enum discriminants correctly for corner cases caused +//! by layout optimizations. + +const OVERFLOW: usize = { + // Tests for https://github.com/rust-lang/rust/issues/62138. + #[repr(u8)] + #[allow(dead_code)] + enum WithWraparoundInvalidValues { + X = 1, + Y = 254, + } + + #[allow(dead_code)] + enum Foo { + A, + B, + C(WithWraparoundInvalidValues), + } + + let x = Foo::B; + match x { + Foo::B => 0, + _ => panic!(), + } +}; + +const MORE_OVERFLOW: usize = { + pub enum Infallible {} + + // The check that the `bool` field of `V1` is encoding a "niche variant" + // (i.e. not `V1`, so `V3` or `V4`) used to be mathematically incorrect, + // causing valid `V1` values to be interpreted as other variants. + #[allow(dead_code)] + pub enum E1 { + V1 { f: bool }, + V2 { f: Infallible }, + V3, + V4, + } + + // Computing the discriminant used to be done using the niche type (here `u8`, + // from the `bool` field of `V1`), overflowing for variants with large enough + // indices (`V3` and `V4`), causing them to be interpreted as other variants. + #[allow(dead_code)] + pub enum E2<X> { + V1 { f: bool }, + + /*_00*/ _01(X), _02(X), _03(X), _04(X), _05(X), _06(X), _07(X), + _08(X), _09(X), _0A(X), _0B(X), _0C(X), _0D(X), _0E(X), _0F(X), + _10(X), _11(X), _12(X), _13(X), _14(X), _15(X), _16(X), _17(X), + _18(X), _19(X), _1A(X), _1B(X), _1C(X), _1D(X), _1E(X), _1F(X), + _20(X), _21(X), _22(X), _23(X), _24(X), _25(X), _26(X), _27(X), + _28(X), _29(X), _2A(X), _2B(X), _2C(X), _2D(X), _2E(X), _2F(X), + _30(X), _31(X), _32(X), _33(X), _34(X), _35(X), _36(X), _37(X), + _38(X), _39(X), _3A(X), _3B(X), _3C(X), _3D(X), _3E(X), _3F(X), + _40(X), _41(X), _42(X), _43(X), _44(X), _45(X), _46(X), _47(X), + _48(X), _49(X), _4A(X), _4B(X), _4C(X), _4D(X), _4E(X), _4F(X), + _50(X), _51(X), _52(X), _53(X), _54(X), _55(X), _56(X), _57(X), + _58(X), _59(X), _5A(X), _5B(X), _5C(X), _5D(X), _5E(X), _5F(X), + _60(X), _61(X), _62(X), _63(X), _64(X), _65(X), _66(X), _67(X), + _68(X), _69(X), _6A(X), _6B(X), _6C(X), _6D(X), _6E(X), _6F(X), + _70(X), _71(X), _72(X), _73(X), _74(X), _75(X), _76(X), _77(X), + _78(X), _79(X), _7A(X), _7B(X), _7C(X), _7D(X), _7E(X), _7F(X), + _80(X), _81(X), _82(X), _83(X), _84(X), _85(X), _86(X), _87(X), + _88(X), _89(X), _8A(X), _8B(X), _8C(X), _8D(X), _8E(X), _8F(X), + _90(X), _91(X), _92(X), _93(X), _94(X), _95(X), _96(X), _97(X), + _98(X), _99(X), _9A(X), _9B(X), _9C(X), _9D(X), _9E(X), _9F(X), + _A0(X), _A1(X), _A2(X), _A3(X), _A4(X), _A5(X), _A6(X), _A7(X), + _A8(X), _A9(X), _AA(X), _AB(X), _AC(X), _AD(X), _AE(X), _AF(X), + _B0(X), _B1(X), _B2(X), _B3(X), _B4(X), _B5(X), _B6(X), _B7(X), + _B8(X), _B9(X), _BA(X), _BB(X), _BC(X), _BD(X), _BE(X), _BF(X), + _C0(X), _C1(X), _C2(X), _C3(X), _C4(X), _C5(X), _C6(X), _C7(X), + _C8(X), _C9(X), _CA(X), _CB(X), _CC(X), _CD(X), _CE(X), _CF(X), + _D0(X), _D1(X), _D2(X), _D3(X), _D4(X), _D5(X), _D6(X), _D7(X), + _D8(X), _D9(X), _DA(X), _DB(X), _DC(X), _DD(X), _DE(X), _DF(X), + _E0(X), _E1(X), _E2(X), _E3(X), _E4(X), _E5(X), _E6(X), _E7(X), + _E8(X), _E9(X), _EA(X), _EB(X), _EC(X), _ED(X), _EE(X), _EF(X), + _F0(X), _F1(X), _F2(X), _F3(X), _F4(X), _F5(X), _F6(X), _F7(X), + _F8(X), _F9(X), _FA(X), _FB(X), _FC(X), _FD(X), _FE(X), _FF(X), + + V3, + V4, + } + + if let E1::V2 { .. } = (E1::V1 { f: true }) { + unreachable!() + } + if let E1::V1 { .. } = (E1::V1 { f: true }) { + } else { + unreachable!() + } + + if let E2::V1 { .. } = E2::V3::<Infallible> { + unreachable!() + } + if let E2::V3 { .. } = E2::V3::<Infallible> { + } else { + unreachable!() + } + + 0 +}; + +fn main() { + assert_eq!(OVERFLOW, 0); + assert_eq!(MORE_OVERFLOW, 0); +} diff --git a/src/test/ui/enum-discriminant/repr128.rs b/src/test/ui/enum-discriminant/repr128.rs new file mode 100644 index 000000000..00021a07b --- /dev/null +++ b/src/test/ui/enum-discriminant/repr128.rs @@ -0,0 +1,45 @@ +// run-pass +#![feature(repr128, core_intrinsics, discriminant_kind)] +//~^ WARN the feature `repr128` is incomplete + +use std::intrinsics::discriminant_value; +use std::marker::DiscriminantKind; + +#[repr(i128)] +enum Signed { + Zero = 0, + Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f, + U64Limit = u64::MAX as i128 + 1, + SmallNegative = -1, + BigNegative = i128::MIN, + Next, +} + +#[repr(u128)] +enum Unsigned { + Zero = 0, + Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f, + U64Limit = u64::MAX as u128 + 1, + Next, +} + +fn discr<T, U>(v: T, value: U) +where + <T as DiscriminantKind>::Discriminant: PartialEq<U>, +{ + assert!(discriminant_value(&v) == value); +} + +fn main() { + discr(Signed::Zero, 0); + discr(Signed::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f); + discr(Signed::U64Limit, u64::MAX as i128 + 1); + discr(Signed::SmallNegative, -1); + discr(Signed::BigNegative, i128::MIN); + discr(Signed::Next, i128::MIN + 1); + + discr(Unsigned::Zero, 0); + discr(Unsigned::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f); + discr(Unsigned::U64Limit, u64::MAX as u128 + 1); + discr(Unsigned::Next, u64::MAX as u128 + 2); +} diff --git a/src/test/ui/enum-discriminant/repr128.stderr b/src/test/ui/enum-discriminant/repr128.stderr new file mode 100644 index 000000000..88adfb174 --- /dev/null +++ b/src/test/ui/enum-discriminant/repr128.stderr @@ -0,0 +1,11 @@ +warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/repr128.rs:2:12 + | +LL | #![feature(repr128, core_intrinsics, discriminant_kind)] + | ^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + +warning: 1 warning emitted + diff --git a/src/test/ui/enum/enum-and-module-in-same-scope.rs b/src/test/ui/enum/enum-and-module-in-same-scope.rs new file mode 100644 index 000000000..cc6e199bd --- /dev/null +++ b/src/test/ui/enum/enum-and-module-in-same-scope.rs @@ -0,0 +1,10 @@ +enum Foo { + X +} + +mod Foo { //~ ERROR the name `Foo` is defined multiple times + pub static X: isize = 42; + fn f() { f() } // Check that this does not result in a resolution error +} + +fn main() {} diff --git a/src/test/ui/enum/enum-and-module-in-same-scope.stderr b/src/test/ui/enum/enum-and-module-in-same-scope.stderr new file mode 100644 index 000000000..538898c2f --- /dev/null +++ b/src/test/ui/enum/enum-and-module-in-same-scope.stderr @@ -0,0 +1,14 @@ +error[E0428]: the name `Foo` is defined multiple times + --> $DIR/enum-and-module-in-same-scope.rs:5:1 + | +LL | enum Foo { + | -------- previous definition of the type `Foo` here +... +LL | mod Foo { + | ^^^^^^^ `Foo` redefined here + | + = note: `Foo` must be defined only once in the type namespace of this module + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/ui/enum/enum-discrim-autosizing.rs b/src/test/ui/enum/enum-discrim-autosizing.rs new file mode 100644 index 000000000..27fab1bb5 --- /dev/null +++ b/src/test/ui/enum/enum-discrim-autosizing.rs @@ -0,0 +1,14 @@ +// With no repr attribute the discriminant will default to isize. +// On 32-bit architectures this is equivalent to i32 so the variants +// collide. On other architectures we need compilation to fail anyway, +// so force the repr. +#[cfg_attr(not(target_pointer_width = "32"), repr(i32))] +enum Eu64 { + //~^ ERROR discriminant value `0` assigned more than once + Au64 = 0, + //~^NOTE first assignment of `0` + Bu64 = 0x8000_0000_0000_0000 + //~^NOTE second assignment of `0` (overflowed from `9223372036854775808`) +} + +fn main() {} diff --git a/src/test/ui/enum/enum-discrim-autosizing.stderr b/src/test/ui/enum/enum-discrim-autosizing.stderr new file mode 100644 index 000000000..eacea86d6 --- /dev/null +++ b/src/test/ui/enum/enum-discrim-autosizing.stderr @@ -0,0 +1,15 @@ +error[E0081]: discriminant value `0` assigned more than once + --> $DIR/enum-discrim-autosizing.rs:6:1 + | +LL | enum Eu64 { + | ^^^^^^^^^ +LL | +LL | Au64 = 0, + | - first assignment of `0` +LL | +LL | Bu64 = 0x8000_0000_0000_0000 + | --------------------- second assignment of `0` (overflowed from `9223372036854775808`) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0081`. diff --git a/src/test/ui/enum/enum-discrim-too-small.rs b/src/test/ui/enum/enum-discrim-too-small.rs new file mode 100644 index 000000000..e49841402 --- /dev/null +++ b/src/test/ui/enum/enum-discrim-too-small.rs @@ -0,0 +1,38 @@ +#[repr(u8)] +enum Eu8 { + Au8 = 23, + Bu8 = 223, + Cu8 = -23, + //~^ ERROR cannot apply unary operator `-` to type `u8` +} + +#[repr(u16)] +enum Eu16 { + Au16 = 23, + Bu16 = 55555, + Cu16 = -22333, + //~^ ERROR cannot apply unary operator `-` to type `u16` +} + +#[repr(u32)] +enum Eu32 { + Au32 = 23, + Bu32 = 3_000_000_000, + Cu32 = -2_000_000_000, + //~^ ERROR cannot apply unary operator `-` to type `u32` +} + +#[repr(u64)] +enum Eu64 { + Au32 = 23, + Bu32 = 3_000_000_000, + Cu32 = -2_000_000_000, + //~^ ERROR cannot apply unary operator `-` to type `u64` +} + +// u64 currently allows negative numbers, and i64 allows numbers greater than `1<<63`. This is a +// little counterintuitive, but since the discriminant can store all the bits, and extracting it +// with a cast requires specifying the signedness, there is no loss of information in those cases. +// This also applies to isize and usize on 64-bit targets. + +pub fn main() { } diff --git a/src/test/ui/enum/enum-discrim-too-small.stderr b/src/test/ui/enum/enum-discrim-too-small.stderr new file mode 100644 index 000000000..40205d95b --- /dev/null +++ b/src/test/ui/enum/enum-discrim-too-small.stderr @@ -0,0 +1,35 @@ +error[E0600]: cannot apply unary operator `-` to type `u8` + --> $DIR/enum-discrim-too-small.rs:5:11 + | +LL | Cu8 = -23, + | ^^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated + +error[E0600]: cannot apply unary operator `-` to type `u16` + --> $DIR/enum-discrim-too-small.rs:13:12 + | +LL | Cu16 = -22333, + | ^^^^^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated + +error[E0600]: cannot apply unary operator `-` to type `u32` + --> $DIR/enum-discrim-too-small.rs:21:12 + | +LL | Cu32 = -2_000_000_000, + | ^^^^^^^^^^^^^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated + +error[E0600]: cannot apply unary operator `-` to type `u64` + --> $DIR/enum-discrim-too-small.rs:29:12 + | +LL | Cu32 = -2_000_000_000, + | ^^^^^^^^^^^^^^ cannot apply unary operator `-` + | + = note: unsigned values cannot be negated + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0600`. diff --git a/src/test/ui/enum/enum-discrim-too-small2.rs b/src/test/ui/enum/enum-discrim-too-small2.rs new file mode 100644 index 000000000..85cd73d6f --- /dev/null +++ b/src/test/ui/enum/enum-discrim-too-small2.rs @@ -0,0 +1,37 @@ +#![deny(overflowing_literals)] +#![allow(dead_code)] + +#[repr(i8)] +enum Ei8 { + Ai8 = 23, + Bi8 = -23, + Ci8 = 223, //~ ERROR literal out of range for `i8` +} + +#[repr(i16)] +enum Ei16 { + Ai16 = 23, + Bi16 = -22333, + Ci16 = 55555, //~ ERROR literal out of range for `i16` +} + +#[repr(i32)] +enum Ei32 { + Ai32 = 23, + Bi32 = -2_000_000_000, + Ci32 = 3_000_000_000, //~ ERROR literal out of range for `i32` +} + +#[repr(i64)] +enum Ei64 { + Ai64 = 23, + Bi64 = -9223372036854775808, + Ci64 = 9223372036854775809, //~ ERROR literal out of range for `i64` +} + +// u64 currently allows negative numbers, and i64 allows numbers greater than `1<<63`. This is a +// little counterintuitive, but since the discriminant can store all the bits, and extracting it +// with a cast requires specifying the signedness, there is no loss of information in those cases. +// This also applies to isize and usize on 64-bit targets. + +pub fn main() { } diff --git a/src/test/ui/enum/enum-discrim-too-small2.stderr b/src/test/ui/enum/enum-discrim-too-small2.stderr new file mode 100644 index 000000000..438306795 --- /dev/null +++ b/src/test/ui/enum/enum-discrim-too-small2.stderr @@ -0,0 +1,43 @@ +error: literal out of range for `i8` + --> $DIR/enum-discrim-too-small2.rs:8:11 + | +LL | Ci8 = 223, + | ^^^ + | +note: the lint level is defined here + --> $DIR/enum-discrim-too-small2.rs:1:9 + | +LL | #![deny(overflowing_literals)] + | ^^^^^^^^^^^^^^^^^^^^ + = note: the literal `223` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u8` instead + +error: literal out of range for `i16` + --> $DIR/enum-discrim-too-small2.rs:15:12 + | +LL | Ci16 = 55555, + | ^^^^^ + | + = note: the literal `55555` does not fit into the type `i16` whose range is `-32768..=32767` + = help: consider using the type `u16` instead + +error: literal out of range for `i32` + --> $DIR/enum-discrim-too-small2.rs:22:12 + | +LL | Ci32 = 3_000_000_000, + | ^^^^^^^^^^^^^ + | + = note: the literal `3_000_000_000` does not fit into the type `i32` whose range is `-2147483648..=2147483647` + = help: consider using the type `u32` instead + +error: literal out of range for `i64` + --> $DIR/enum-discrim-too-small2.rs:29:12 + | +LL | Ci64 = 9223372036854775809, + | ^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `9223372036854775809` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` + = help: consider using the type `u64` instead + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/enum/enum-in-scope.rs b/src/test/ui/enum/enum-in-scope.rs new file mode 100644 index 000000000..df14bc62e --- /dev/null +++ b/src/test/ui/enum/enum-in-scope.rs @@ -0,0 +1,7 @@ +#![allow(non_camel_case_types)] + +struct hello(isize); + +fn main() { + let hello = 0; //~ERROR let bindings cannot shadow tuple structs +} diff --git a/src/test/ui/enum/enum-in-scope.stderr b/src/test/ui/enum/enum-in-scope.stderr new file mode 100644 index 000000000..49a01abcb --- /dev/null +++ b/src/test/ui/enum/enum-in-scope.stderr @@ -0,0 +1,12 @@ +error[E0530]: let bindings cannot shadow tuple structs + --> $DIR/enum-in-scope.rs:6:9 + | +LL | struct hello(isize); + | -------------------- the tuple struct `hello` is defined here +... +LL | let hello = 0; + | ^^^^^ cannot be named the same as a tuple struct + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0530`. diff --git a/src/test/ui/enum/enum-size-variance.rs b/src/test/ui/enum/enum-size-variance.rs new file mode 100644 index 000000000..082bd0dcf --- /dev/null +++ b/src/test/ui/enum/enum-size-variance.rs @@ -0,0 +1,35 @@ +// run-pass + +#![warn(variant_size_differences)] +#![allow(dead_code)] + +// Note that the following test works because all fields of the enum variants are of the same size. +// If this test is modified and the reordering logic in librustc/ty/layout.rs kicks in, it fails. + +enum Enum1 { } + +enum Enum2 { A, B, C } + +enum Enum3 { D(i64), E, F } + +enum Enum4 { H(i64), I(i64), J } + +enum Enum5 { + L(i64, i64, i64, i64), //~ WARNING three times larger + M(i64), + N +} + +enum Enum6<T, U> { + O(T), + P(U), + Q(i64) +} + +#[allow(variant_size_differences)] +enum Enum7 { + R(i64, i64, i64, i64), + S(i64), + T +} +pub fn main() { } diff --git a/src/test/ui/enum/enum-size-variance.stderr b/src/test/ui/enum/enum-size-variance.stderr new file mode 100644 index 000000000..6012033dc --- /dev/null +++ b/src/test/ui/enum/enum-size-variance.stderr @@ -0,0 +1,14 @@ +warning: enum variant is more than three times larger (32 bytes) than the next largest + --> $DIR/enum-size-variance.rs:18:5 + | +LL | L(i64, i64, i64, i64), + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/enum-size-variance.rs:3:9 + | +LL | #![warn(variant_size_differences)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/src/test/ui/enum/enum-to-float-cast-2.rs b/src/test/ui/enum/enum-to-float-cast-2.rs new file mode 100644 index 000000000..c861b5ed9 --- /dev/null +++ b/src/test/ui/enum/enum-to-float-cast-2.rs @@ -0,0 +1,18 @@ +// Tests that enum-to-float casts are disallowed. + +enum E { + L0 = -1, + H0 = 1 +} + +enum F { + L1 = 1, + H1 = 0xFFFFFFFFFFFFFFFF +} + +pub fn main() { + let a = E::L0 as f32; //~ ERROR casting + let c = F::H1 as f32; //~ ERROR casting + assert_eq!(a, -1.0f32); + assert_eq!(c, -1.0f32); +} diff --git a/src/test/ui/enum/enum-to-float-cast-2.stderr b/src/test/ui/enum/enum-to-float-cast-2.stderr new file mode 100644 index 000000000..2bc414098 --- /dev/null +++ b/src/test/ui/enum/enum-to-float-cast-2.stderr @@ -0,0 +1,19 @@ +error[E0606]: casting `E` as `f32` is invalid + --> $DIR/enum-to-float-cast-2.rs:14:13 + | +LL | let a = E::L0 as f32; + | ^^^^^^^^^^^^ + | + = help: cast through an integer first + +error[E0606]: casting `F` as `f32` is invalid + --> $DIR/enum-to-float-cast-2.rs:15:13 + | +LL | let c = F::H1 as f32; + | ^^^^^^^^^^^^ + | + = help: cast through an integer first + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/enum/enum-to-float-cast.rs b/src/test/ui/enum/enum-to-float-cast.rs new file mode 100644 index 000000000..05acdfd34 --- /dev/null +++ b/src/test/ui/enum/enum-to-float-cast.rs @@ -0,0 +1,21 @@ +// Tests that enum-to-float casts are disallowed. + +enum E { + L0 = -1, + H0 = 1 +} + +enum F { + L1 = 1, + H1 = 0xFFFFFFFFFFFFFFFF +} + +static C0: f32 = E::L0 as f32; //~ ERROR casting +static C1: f32 = F::H1 as f32; //~ ERROR casting + +pub fn main() { + let b = C0; + let d = C1; + assert_eq!(b, -1.0f32); + assert_eq!(d, -1.0f32); +} diff --git a/src/test/ui/enum/enum-to-float-cast.stderr b/src/test/ui/enum/enum-to-float-cast.stderr new file mode 100644 index 000000000..191606d8d --- /dev/null +++ b/src/test/ui/enum/enum-to-float-cast.stderr @@ -0,0 +1,19 @@ +error[E0606]: casting `E` as `f32` is invalid + --> $DIR/enum-to-float-cast.rs:13:18 + | +LL | static C0: f32 = E::L0 as f32; + | ^^^^^^^^^^^^ + | + = help: cast through an integer first + +error[E0606]: casting `F` as `f32` is invalid + --> $DIR/enum-to-float-cast.rs:14:18 + | +LL | static C1: f32 = F::H1 as f32; + | ^^^^^^^^^^^^ + | + = help: cast through an integer first + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/enum/enum-variant-type-2.rs b/src/test/ui/enum/enum-variant-type-2.rs new file mode 100644 index 000000000..27286a0a3 --- /dev/null +++ b/src/test/ui/enum/enum-variant-type-2.rs @@ -0,0 +1,9 @@ +// Test that enum variants are not actually types. + +enum Foo { + Bar +} + +fn foo(x: Foo::Bar) {} //~ ERROR expected type, found variant `Foo::Bar` + +fn main() {} diff --git a/src/test/ui/enum/enum-variant-type-2.stderr b/src/test/ui/enum/enum-variant-type-2.stderr new file mode 100644 index 000000000..7e8453c61 --- /dev/null +++ b/src/test/ui/enum/enum-variant-type-2.stderr @@ -0,0 +1,12 @@ +error[E0573]: expected type, found variant `Foo::Bar` + --> $DIR/enum-variant-type-2.rs:7:11 + | +LL | fn foo(x: Foo::Bar) {} + | ^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0573`. diff --git a/src/test/ui/enum/issue-42747.rs b/src/test/ui/enum/issue-42747.rs new file mode 100644 index 000000000..fec658782 --- /dev/null +++ b/src/test/ui/enum/issue-42747.rs @@ -0,0 +1,46 @@ +// run-pass +macro_rules! fooN { + ($cur:ident $prev:ty) => { + #[allow(dead_code)] + enum $cur { + Empty, + First($prev), + Second($prev), + Third($prev), + Fourth($prev), + } + } +} + +fooN!(Foo0 ()); +fooN!(Foo1 Foo0); +fooN!(Foo2 Foo1); +fooN!(Foo3 Foo2); +fooN!(Foo4 Foo3); +fooN!(Foo5 Foo4); +fooN!(Foo6 Foo5); +fooN!(Foo7 Foo6); +fooN!(Foo8 Foo7); +fooN!(Foo9 Foo8); +fooN!(Foo10 Foo9); +fooN!(Foo11 Foo10); +fooN!(Foo12 Foo11); +fooN!(Foo13 Foo12); +fooN!(Foo14 Foo13); +fooN!(Foo15 Foo14); +fooN!(Foo16 Foo15); +fooN!(Foo17 Foo16); +fooN!(Foo18 Foo17); +fooN!(Foo19 Foo18); +fooN!(Foo20 Foo19); +fooN!(Foo21 Foo20); +fooN!(Foo22 Foo21); +fooN!(Foo23 Foo22); +fooN!(Foo24 Foo23); +fooN!(Foo25 Foo24); +fooN!(Foo26 Foo25); +fooN!(Foo27 Foo26); + +fn main() { + let _foo = Foo27::Empty; +} diff --git a/src/test/ui/enum/issue-67945-1.rs b/src/test/ui/enum/issue-67945-1.rs new file mode 100644 index 000000000..f4697344c --- /dev/null +++ b/src/test/ui/enum/issue-67945-1.rs @@ -0,0 +1,8 @@ +enum Bug<S> { //~ ERROR parameter `S` is never used + Var = { + let x: S = 0; //~ ERROR generic parameters may not be used + 0 + }, +} + +fn main() {} diff --git a/src/test/ui/enum/issue-67945-1.stderr b/src/test/ui/enum/issue-67945-1.stderr new file mode 100644 index 000000000..8f1b5b38e --- /dev/null +++ b/src/test/ui/enum/issue-67945-1.stderr @@ -0,0 +1,21 @@ +error: generic parameters may not be used in const operations + --> $DIR/issue-67945-1.rs:3:16 + | +LL | let x: S = 0; + | ^ cannot perform const operation using `S` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error[E0392]: parameter `S` is never used + --> $DIR/issue-67945-1.rs:1:10 + | +LL | enum Bug<S> { + | ^ unused parameter + | + = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `S` to be a const parameter, use `const S: usize` instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/enum/issue-67945-2.rs b/src/test/ui/enum/issue-67945-2.rs new file mode 100644 index 000000000..e5044468d --- /dev/null +++ b/src/test/ui/enum/issue-67945-2.rs @@ -0,0 +1,8 @@ +#![feature(type_ascription)] + +enum Bug<S> { //~ ERROR parameter `S` is never used + Var = 0: S, + //~^ ERROR generic parameters may not be used +} + +fn main() {} diff --git a/src/test/ui/enum/issue-67945-2.stderr b/src/test/ui/enum/issue-67945-2.stderr new file mode 100644 index 000000000..4f5e236a3 --- /dev/null +++ b/src/test/ui/enum/issue-67945-2.stderr @@ -0,0 +1,21 @@ +error: generic parameters may not be used in const operations + --> $DIR/issue-67945-2.rs:4:14 + | +LL | Var = 0: S, + | ^ cannot perform const operation using `S` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error[E0392]: parameter `S` is never used + --> $DIR/issue-67945-2.rs:3:10 + | +LL | enum Bug<S> { + | ^ unused parameter + | + = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `S` to be a const parameter, use `const S: usize` instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/enum/nested-enum.rs b/src/test/ui/enum/nested-enum.rs new file mode 100644 index 000000000..80957b8a1 --- /dev/null +++ b/src/test/ui/enum/nested-enum.rs @@ -0,0 +1,8 @@ +enum Foo { + enum Bar { Baz }, //~ ERROR `enum` definition cannot be nested inside `enum` + struct Quux { field: u8 }, //~ ERROR `struct` definition cannot be nested inside `enum` + union Wibble { field: u8 }, //~ ERROR `union` definition cannot be nested inside `enum` + Bat, +} + +fn main() { } diff --git a/src/test/ui/enum/nested-enum.stderr b/src/test/ui/enum/nested-enum.stderr new file mode 100644 index 000000000..7d6f57e88 --- /dev/null +++ b/src/test/ui/enum/nested-enum.stderr @@ -0,0 +1,26 @@ +error: `enum` definition cannot be nested inside `enum` + --> $DIR/nested-enum.rs:2:5 + | +LL | enum Bar { Baz }, + | ^^^^------------ + | | + | help: consider creating a new `enum` definition instead of nesting + +error: `struct` definition cannot be nested inside `enum` + --> $DIR/nested-enum.rs:3:5 + | +LL | struct Quux { field: u8 }, + | ^^^^^^------------------- + | | + | help: consider creating a new `struct` definition instead of nesting + +error: `union` definition cannot be nested inside `enum` + --> $DIR/nested-enum.rs:4:5 + | +LL | union Wibble { field: u8 }, + | ^^^^^--------------------- + | | + | help: consider creating a new `union` definition instead of nesting + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/enum/suggest-default-attribute.rs b/src/test/ui/enum/suggest-default-attribute.rs new file mode 100644 index 000000000..1d7567e60 --- /dev/null +++ b/src/test/ui/enum/suggest-default-attribute.rs @@ -0,0 +1,8 @@ +pub enum Test { //~ HELP consider adding a derive + #[default] + //~^ ERROR cannot find attribute `default` in this scope + First, + Second, +} + +fn main() {} diff --git a/src/test/ui/enum/suggest-default-attribute.stderr b/src/test/ui/enum/suggest-default-attribute.stderr new file mode 100644 index 000000000..fb830d3f7 --- /dev/null +++ b/src/test/ui/enum/suggest-default-attribute.stderr @@ -0,0 +1,14 @@ +error: cannot find attribute `default` in this scope + --> $DIR/suggest-default-attribute.rs:2:7 + | +LL | #[default] + | ^^^^^^^ + | +help: consider adding a derive + | +LL + #[derive(Default)] +LL ~ pub enum Test { + | + +error: aborting due to previous error + diff --git a/src/test/ui/enum/union-in-enum.rs b/src/test/ui/enum/union-in-enum.rs new file mode 100644 index 000000000..048913e25 --- /dev/null +++ b/src/test/ui/enum/union-in-enum.rs @@ -0,0 +1,13 @@ +// This test checks that the union keyword +// is accepted as the name of an enum variant +// when not followed by an identifier +// This special case exists because `union` is a contextual keyword. + +#![allow(warnings)] + +// check-pass + +enum A { union } +enum B { union {} } +enum C { union() } +fn main(){} |