add tests for enum discriminants

This commit is contained in:
Bastian Kauschke 2020-04-05 22:20:38 +02:00
parent ff2940a9f4
commit d6cb5405dd
5 changed files with 169 additions and 0 deletions

View File

@ -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)));
}

View File

@ -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]);
}

View File

@ -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() {}

View File

@ -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`.

View File

@ -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<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_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);
}