Skip to content

Commit d6cb540

Browse files
committed
add tests for enum discriminants
1 parent ff2940a commit d6cb540

5 files changed

+169
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// run-pass
2+
#![feature(core_intrinsics)]
3+
4+
use std::intrinsics::discriminant_value;
5+
6+
struct Zst;
7+
8+
struct Struct {
9+
_a: u32,
10+
}
11+
12+
union Union {
13+
_a: u32,
14+
}
15+
16+
fn check(v: u8) {
17+
assert_eq!(v, 0);
18+
}
19+
20+
pub fn generic<T>()
21+
where
22+
for<'a> T: Fn(&'a isize),
23+
{
24+
let v: Vec<T> = Vec::new();
25+
let _: u8 = discriminant_value(&v);
26+
}
27+
28+
fn main() {
29+
// check that we use `u8` as the discriminant value
30+
// for everything that is not an enum.
31+
check(discriminant_value(&true));
32+
check(discriminant_value(&'a'));
33+
check(discriminant_value(&7));
34+
check(discriminant_value(&7.0));
35+
check(discriminant_value(&Zst));
36+
check(discriminant_value(&Struct { _a: 7 }));
37+
check(discriminant_value(&Union { _a: 7 }));
38+
check(discriminant_value(&[7, 77]));
39+
check(discriminant_value(&(7 as *const ())));
40+
check(discriminant_value(&(7 as *mut ())));
41+
check(discriminant_value(&&7));
42+
check(discriminant_value(&&mut 7));
43+
check(discriminant_value(&check));
44+
let fn_ptr: fn(u8) = check;
45+
check(discriminant_value(&fn_ptr));
46+
let hrtb: for<'a> fn(&'a str) -> &'a str = |x| x;
47+
check(discriminant_value(&hrtb));
48+
check(discriminant_value(&(7, 77, 777)));
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// run-pass
2+
#![feature(core_intrinsics, repr128)]
3+
4+
use std::intrinsics::discriminant_value;
5+
6+
enum E1 {
7+
A,
8+
B,
9+
}
10+
11+
#[repr(i8)]
12+
enum E2 {
13+
A = 7,
14+
B = -2,
15+
}
16+
17+
#[repr(C)]
18+
enum E3 {
19+
A = 42,
20+
B = 100,
21+
}
22+
23+
#[repr(i128)]
24+
enum E4 {
25+
A = 0x1223_3445_5667_7889,
26+
B = -0x1223_3445_5667_7889,
27+
}
28+
29+
fn main() {
30+
let mut target: [isize; 3] = [0, 0, 0];
31+
target[1] = discriminant_value(&E1::A);
32+
assert_eq!(target, [0, 0, 0]);
33+
target[1] = discriminant_value(&E1::B);
34+
assert_eq!(target, [0, 1, 0]);
35+
36+
let mut target: [i8; 3] = [0, 0, 0];
37+
target[1] = discriminant_value(&E2::A);
38+
assert_eq!(target, [0, 7, 0]);
39+
target[1] = discriminant_value(&E2::B);
40+
assert_eq!(target, [0, -2, 0]);
41+
42+
let mut target: [isize; 3] = [0, 0, 0];
43+
target[1] = discriminant_value(&E3::A);
44+
assert_eq!(target, [0, 42, 0]);
45+
target[1] = discriminant_value(&E3::B);
46+
assert_eq!(target, [0, 100, 0]);
47+
48+
let mut target: [i128; 3] = [0, 0, 0];
49+
target[1] = discriminant_value(&E4::A);
50+
assert_eq!(target, [0, 0x1223_3445_5667_7889, 0]);
51+
target[1] = discriminant_value(&E4::B);
52+
assert_eq!(target, [0, -0x1223_3445_5667_7889, 0]);
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![feature(discriminant_kind)]
2+
3+
use std::marker::DiscriminantKind;
4+
5+
enum Uninhabited {}
6+
7+
struct NewType;
8+
9+
impl DiscriminantKind for NewType {
10+
//~^ ERROR explicit impls for the `DiscriminantKind` trait are not permitted
11+
type Discriminant = Uninhabited;
12+
}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0322]: explicit impls for the `DiscriminantKind` trait are not permitted
2+
--> $DIR/forbidden-discriminant-kind-impl.rs:9:1
3+
|
4+
LL | impl DiscriminantKind for NewType {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'DiscriminantKind' not allowed
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0322`.
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// run-pass
2+
#![feature(repr128, core_intrinsics, discriminant_kind)]
3+
4+
use std::intrinsics::discriminant_value;
5+
use std::marker::DiscriminantKind;
6+
7+
#[repr(i128)]
8+
enum Signed {
9+
Zero = 0,
10+
Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f,
11+
U64Limit = u64::max_value() as i128 + 1,
12+
SmallNegative = -1,
13+
BigNegative = i128::min_value(),
14+
Next,
15+
}
16+
17+
#[repr(u128)]
18+
enum Unsigned {
19+
Zero = 0,
20+
Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f,
21+
U64Limit = u64::max_value() as u128 + 1,
22+
Next,
23+
}
24+
25+
fn discr<T, U>(v: T, value: U)
26+
where
27+
<T as DiscriminantKind>::Discriminant: PartialEq<U>,
28+
{
29+
assert!(discriminant_value(&v) == value);
30+
}
31+
32+
fn main() {
33+
discr(Signed::Zero, 0);
34+
discr(Signed::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f);
35+
discr(Signed::U64Limit, u64::max_value() as i128 + 1);
36+
discr(Signed::SmallNegative, -1);
37+
discr(Signed::BigNegative, i128::min_value());
38+
discr(Signed::Next, i128::min_value() + 1);
39+
40+
discr(Unsigned::Zero, 0);
41+
discr(Unsigned::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f);
42+
discr(Unsigned::U64Limit, u64::max_value() as u128 + 1);
43+
discr(Unsigned::Next, u64::max_value() as u128 + 2);
44+
}

0 commit comments

Comments
 (0)