diff options
Diffstat (limited to 'tests/ui/enum')
28 files changed, 545 insertions, 0 deletions
diff --git a/tests/ui/enum/enum-and-module-in-same-scope.rs b/tests/ui/enum/enum-and-module-in-same-scope.rs new file mode 100644 index 000000000..cc6e199bd --- /dev/null +++ b/tests/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/tests/ui/enum/enum-and-module-in-same-scope.stderr b/tests/ui/enum/enum-and-module-in-same-scope.stderr new file mode 100644 index 000000000..538898c2f --- /dev/null +++ b/tests/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/tests/ui/enum/enum-discrim-autosizing.rs b/tests/ui/enum/enum-discrim-autosizing.rs new file mode 100644 index 000000000..fc94d281c --- /dev/null +++ b/tests/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 `0` assigned here + Bu64 = 0x8000_0000_0000_0000 + //~^NOTE `0` (overflowed from `9223372036854775808`) assigned here +} + +fn main() {} diff --git a/tests/ui/enum/enum-discrim-autosizing.stderr b/tests/ui/enum/enum-discrim-autosizing.stderr new file mode 100644 index 000000000..be3d7c64e --- /dev/null +++ b/tests/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, + | - `0` assigned here +LL | +LL | Bu64 = 0x8000_0000_0000_0000 + | --------------------- `0` (overflowed from `9223372036854775808`) assigned here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0081`. diff --git a/tests/ui/enum/enum-discrim-too-small.rs b/tests/ui/enum/enum-discrim-too-small.rs new file mode 100644 index 000000000..e49841402 --- /dev/null +++ b/tests/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/tests/ui/enum/enum-discrim-too-small.stderr b/tests/ui/enum/enum-discrim-too-small.stderr new file mode 100644 index 000000000..40205d95b --- /dev/null +++ b/tests/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/tests/ui/enum/enum-discrim-too-small2.rs b/tests/ui/enum/enum-discrim-too-small2.rs new file mode 100644 index 000000000..85cd73d6f --- /dev/null +++ b/tests/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/tests/ui/enum/enum-discrim-too-small2.stderr b/tests/ui/enum/enum-discrim-too-small2.stderr new file mode 100644 index 000000000..f79f7a043 --- /dev/null +++ b/tests/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 literal `223` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u8` instead +note: the lint level is defined here + --> $DIR/enum-discrim-too-small2.rs:1:9 + | +LL | #![deny(overflowing_literals)] + | ^^^^^^^^^^^^^^^^^^^^ + +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/tests/ui/enum/enum-in-scope.rs b/tests/ui/enum/enum-in-scope.rs new file mode 100644 index 000000000..df14bc62e --- /dev/null +++ b/tests/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/tests/ui/enum/enum-in-scope.stderr b/tests/ui/enum/enum-in-scope.stderr new file mode 100644 index 000000000..49a01abcb --- /dev/null +++ b/tests/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/tests/ui/enum/enum-size-variance.rs b/tests/ui/enum/enum-size-variance.rs new file mode 100644 index 000000000..082bd0dcf --- /dev/null +++ b/tests/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/tests/ui/enum/enum-size-variance.stderr b/tests/ui/enum/enum-size-variance.stderr new file mode 100644 index 000000000..6012033dc --- /dev/null +++ b/tests/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/tests/ui/enum/enum-to-float-cast-2.rs b/tests/ui/enum/enum-to-float-cast-2.rs new file mode 100644 index 000000000..c861b5ed9 --- /dev/null +++ b/tests/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/tests/ui/enum/enum-to-float-cast-2.stderr b/tests/ui/enum/enum-to-float-cast-2.stderr new file mode 100644 index 000000000..2bc414098 --- /dev/null +++ b/tests/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/tests/ui/enum/enum-to-float-cast.rs b/tests/ui/enum/enum-to-float-cast.rs new file mode 100644 index 000000000..05acdfd34 --- /dev/null +++ b/tests/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/tests/ui/enum/enum-to-float-cast.stderr b/tests/ui/enum/enum-to-float-cast.stderr new file mode 100644 index 000000000..191606d8d --- /dev/null +++ b/tests/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/tests/ui/enum/enum-variant-type-2.rs b/tests/ui/enum/enum-variant-type-2.rs new file mode 100644 index 000000000..27286a0a3 --- /dev/null +++ b/tests/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/tests/ui/enum/enum-variant-type-2.stderr b/tests/ui/enum/enum-variant-type-2.stderr new file mode 100644 index 000000000..7e8453c61 --- /dev/null +++ b/tests/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/tests/ui/enum/issue-42747.rs b/tests/ui/enum/issue-42747.rs new file mode 100644 index 000000000..fec658782 --- /dev/null +++ b/tests/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/tests/ui/enum/issue-67945-1.rs b/tests/ui/enum/issue-67945-1.rs new file mode 100644 index 000000000..f4697344c --- /dev/null +++ b/tests/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/tests/ui/enum/issue-67945-1.stderr b/tests/ui/enum/issue-67945-1.stderr new file mode 100644 index 000000000..8f1b5b38e --- /dev/null +++ b/tests/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/tests/ui/enum/issue-67945-2.rs b/tests/ui/enum/issue-67945-2.rs new file mode 100644 index 000000000..2eb123b73 --- /dev/null +++ b/tests/ui/enum/issue-67945-2.rs @@ -0,0 +1,8 @@ +#![feature(type_ascription)] + +enum Bug<S> { //~ ERROR parameter `S` is never used + Var = type_ascribe!(0, S), + //~^ ERROR generic parameters may not be used +} + +fn main() {} diff --git a/tests/ui/enum/issue-67945-2.stderr b/tests/ui/enum/issue-67945-2.stderr new file mode 100644 index 000000000..63d3521af --- /dev/null +++ b/tests/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:28 + | +LL | Var = type_ascribe!(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/tests/ui/enum/nested-enum.rs b/tests/ui/enum/nested-enum.rs new file mode 100644 index 000000000..80957b8a1 --- /dev/null +++ b/tests/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/tests/ui/enum/nested-enum.stderr b/tests/ui/enum/nested-enum.stderr new file mode 100644 index 000000000..7d6f57e88 --- /dev/null +++ b/tests/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/tests/ui/enum/suggest-default-attribute.rs b/tests/ui/enum/suggest-default-attribute.rs new file mode 100644 index 000000000..1d7567e60 --- /dev/null +++ b/tests/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/tests/ui/enum/suggest-default-attribute.stderr b/tests/ui/enum/suggest-default-attribute.stderr new file mode 100644 index 000000000..fb830d3f7 --- /dev/null +++ b/tests/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/tests/ui/enum/union-in-enum.rs b/tests/ui/enum/union-in-enum.rs new file mode 100644 index 000000000..048913e25 --- /dev/null +++ b/tests/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(){} |