mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #69825 - lcnr:discriminant, r=oli-obk
make `mem::discriminant` const implements #69821, which could be used as a tracking issue for `const_discriminant`. Should this be added to the meta tracking issue #57563? @Lokathor
This commit is contained in:
commit
dfbbd5d6ea
@ -1862,6 +1862,7 @@ extern "rust-intrinsic" {
|
||||
///
|
||||
/// The stabilized version of this intrinsic is
|
||||
/// [`std::mem::discriminant`](../../std/mem/fn.discriminant.html)
|
||||
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
|
||||
pub fn discriminant_value<T>(v: &T) -> u64;
|
||||
|
||||
/// Rust's "try catch" construct which invokes the function pointer `f` with
|
||||
|
@ -72,6 +72,7 @@
|
||||
#![feature(concat_idents)]
|
||||
#![feature(const_ascii_ctype_on_intrinsics)]
|
||||
#![feature(const_alloc_layout)]
|
||||
#![feature(const_discriminant)]
|
||||
#![feature(const_if_match)]
|
||||
#![feature(const_loop)]
|
||||
#![feature(const_checked_int_methods)]
|
||||
|
@ -870,6 +870,7 @@ impl<T> fmt::Debug for Discriminant<T> {
|
||||
/// assert_ne!(mem::discriminant(&Foo::B(3)), mem::discriminant(&Foo::C(3)));
|
||||
/// ```
|
||||
#[stable(feature = "discriminant_value", since = "1.21.0")]
|
||||
pub fn discriminant<T>(v: &T) -> Discriminant<T> {
|
||||
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
|
||||
pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
|
||||
Discriminant(intrinsics::discriminant_value(v), PhantomData)
|
||||
}
|
||||
|
@ -216,6 +216,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
};
|
||||
self.write_scalar(val, dest)?;
|
||||
}
|
||||
sym::discriminant_value => {
|
||||
let place = self.deref_operand(args[0])?;
|
||||
let discr_val = self.read_discriminant(place.into())?.0;
|
||||
self.write_scalar(Scalar::from_uint(discr_val, dest.layout.size), dest)?;
|
||||
}
|
||||
sym::unchecked_shl
|
||||
| sym::unchecked_shr
|
||||
| sym::unchecked_add
|
||||
|
@ -265,6 +265,7 @@ symbols! {
|
||||
derive,
|
||||
diagnostic,
|
||||
direct,
|
||||
discriminant_value,
|
||||
doc,
|
||||
doc_alias,
|
||||
doc_cfg,
|
||||
|
40
src/test/ui/consts/const_discriminant.rs
Normal file
40
src/test/ui/consts/const_discriminant.rs
Normal file
@ -0,0 +1,40 @@
|
||||
// run-pass
|
||||
#![feature(const_discriminant)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::mem::{discriminant, Discriminant};
|
||||
|
||||
// `discriminant(const_expr)` may get const-propagated.
|
||||
// As we want to check that const-eval is equal to ordinary exection,
|
||||
// we wrap `const_expr` with a function which is not const to prevent this.
|
||||
#[inline(never)]
|
||||
fn identity<T>(x: T) -> T { x }
|
||||
|
||||
enum Test {
|
||||
A(u8),
|
||||
B,
|
||||
C { a: u8, b: u8 },
|
||||
}
|
||||
|
||||
const TEST_A: Discriminant<Test> = discriminant(&Test::A(5));
|
||||
const TEST_A_OTHER: Discriminant<Test> = discriminant(&Test::A(17));
|
||||
const TEST_B: Discriminant<Test> = discriminant(&Test::B);
|
||||
|
||||
enum Void {}
|
||||
|
||||
enum SingleVariant {
|
||||
V,
|
||||
Never(Void),
|
||||
}
|
||||
|
||||
const TEST_V: Discriminant<SingleVariant> = discriminant(&SingleVariant::V);
|
||||
|
||||
fn main() {
|
||||
assert_eq!(TEST_A, TEST_A_OTHER);
|
||||
assert_eq!(TEST_A, discriminant(identity(&Test::A(17))));
|
||||
assert_eq!(TEST_B, discriminant(identity(&Test::B)));
|
||||
assert_ne!(TEST_A, TEST_B);
|
||||
assert_ne!(TEST_B, discriminant(identity(&Test::C { a: 42, b: 7 })));
|
||||
|
||||
assert_eq!(TEST_V, discriminant(identity(&SingleVariant::V)));
|
||||
}
|
Loading…
Reference in New Issue
Block a user