From d6cb5405dd3641c05a1ee45460c1acb9ac9a864c Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 5 Apr 2020 22:20:38 +0200 Subject: [PATCH] add tests for enum discriminants --- .../actually_not_an_enum-discriminant.rs | 49 +++++++++++++++++ .../ui/enum-discriminant/discriminant_size.rs | 53 +++++++++++++++++++ .../forbidden-discriminant-kind-impl.rs | 14 +++++ .../forbidden-discriminant-kind-impl.stderr | 9 ++++ src/test/ui/enum-discriminant/repr128.rs | 44 +++++++++++++++ 5 files changed, 169 insertions(+) create mode 100644 src/test/ui/enum-discriminant/actually_not_an_enum-discriminant.rs create mode 100644 src/test/ui/enum-discriminant/discriminant_size.rs create mode 100644 src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs create mode 100644 src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr create mode 100644 src/test/ui/enum-discriminant/repr128.rs 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 00000000000..6a566ab3a3d --- /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() +where + for<'a> T: Fn(&'a isize), +{ + let v: Vec = 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/discriminant_size.rs b/src/test/ui/enum-discriminant/discriminant_size.rs new file mode 100644 index 00000000000..4cede8c2a2d --- /dev/null +++ b/src/test/ui/enum-discriminant/discriminant_size.rs @@ -0,0 +1,53 @@ +// run-pass +#![feature(core_intrinsics, repr128)] + +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/forbidden-discriminant-kind-impl.rs b/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs new file mode 100644 index 00000000000..4760ca5482a --- /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 00000000000..54360c4f47b --- /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/repr128.rs b/src/test/ui/enum-discriminant/repr128.rs new file mode 100644 index 00000000000..420b6007c6d --- /dev/null +++ b/src/test/ui/enum-discriminant/repr128.rs @@ -0,0 +1,44 @@ +// run-pass +#![feature(repr128, core_intrinsics, discriminant_kind)] + +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_value() as i128 + 1, + SmallNegative = -1, + BigNegative = i128::min_value(), + 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_value() as u128 + 1, + Next, +} + +fn discr(v: T, value: U) +where + ::Discriminant: PartialEq, +{ + 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_value() as i128 + 1); + discr(Signed::SmallNegative, -1); + discr(Signed::BigNegative, i128::min_value()); + discr(Signed::Next, i128::min_value() + 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_value() as u128 + 1); + discr(Unsigned::Next, u64::max_value() as u128 + 2); +}