From d36d351afcb439144621159d8642892cde26eff6 Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Tue, 23 Jun 2020 16:46:24 +0100 Subject: Implement intrinsic --- src/libcore/intrinsics.rs | 15 +++++++++++++++ src/libcore/lib.rs | 1 + src/libcore/mem/mod.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) (limited to 'src/libcore') diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 50e321f9c71..4074087e1e6 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1917,6 +1917,15 @@ extern "rust-intrinsic" { #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")] pub fn discriminant_value(v: &T) -> ::Discriminant; + /// Returns the number of variants of the type `T` cast to a `usize`; + /// if `T` has no variants, returns 0. Uninhabited variants will be counted. + /// + /// The to-be-stabilized version of this intrinsic is + /// [`std::mem::variant_count`](../../std/mem/fn.variant_count.html) + #[rustc_const_unstable(feature = "variant_count", issue = "73662")] + #[cfg(not(bootstrap))] + pub fn variant_count() -> usize; + /// Rust's "try catch" construct which invokes the function pointer `try_fn` /// with the data pointer `data`. /// @@ -1960,6 +1969,12 @@ extern "rust-intrinsic" { pub fn ptr_guaranteed_ne(ptr: *const T, other: *const T) -> bool; } +#[rustc_const_unstable(feature = "variant_count", issue = "73662")] +#[cfg(bootstrap)] +pub const fn variant_count() -> usize { + 0 +} + // Some functions are defined here because they accidentally got made // available in this module on stable. See . // (`transmute` also falls into this category, but it cannot be wrapped due to the diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4eb2fdbd078..2b26e5303a8 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -124,6 +124,7 @@ #![feature(unsized_locals)] #![feature(untagged_unions)] #![feature(unwind_attributes)] +#![feature(variant_count)] #![feature(doc_alias)] #![feature(mmx_target_feature)] #![feature(tbm_target_feature)] diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index 066bb8b3dc7..d041571f260 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -999,3 +999,30 @@ impl fmt::Debug for Discriminant { pub const fn discriminant(v: &T) -> Discriminant { Discriminant(intrinsics::discriminant_value(v)) } + +/// Returns the number of variants in the enum type `T`. +/// +/// If `T` is not an enum, calling this function will not result in undefined behavior, but the +/// return value is unspecified. Equally, if `T` is an enum with more variants than `usize::MAX` +/// the return value is unspecified. Uninhabited variants will be counted. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// +/// enum Void {} +/// enum Foo { A(&'static str), B(i32), C(i32) } +/// +/// assert_eq!(mem::variant_count::(), 0); +/// assert_eq!(mem::variant_count::(), 3); +/// +/// assert_eq!(mem::variant_count::>(), 2); +/// assert_eq!(mem::variant_count::>(), 2); +/// ``` +#[inline(always)] +#[unstable(feature = "variant_count", issue = "73662")] +#[rustc_const_unstable(feature = "variant_count", issue = "73662")] +pub const fn variant_count() -> usize { + intrinsics::variant_count::() +} -- cgit 1.4.1-3-g733a5 From c2dfc25c0eeb74d6c723312d612cd6899058971c Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Wed, 24 Jun 2020 15:10:10 +0100 Subject: Fix tests --- src/libcore/mem/mod.rs | 2 ++ src/test/ui/consts/const-variant-count.rs | 1 + 2 files changed, 3 insertions(+) (limited to 'src/libcore') diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index d041571f260..2be105e68eb 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -1009,6 +1009,8 @@ pub const fn discriminant(v: &T) -> Discriminant { /// # Examples /// /// ``` +/// # #![feature(never_type)] +/// /// use std::mem; /// /// enum Void {} diff --git a/src/test/ui/consts/const-variant-count.rs b/src/test/ui/consts/const-variant-count.rs index f21f6e9c291..455419d2c7f 100644 --- a/src/test/ui/consts/const-variant-count.rs +++ b/src/test/ui/consts/const-variant-count.rs @@ -1,6 +1,7 @@ // run-pass #![allow(dead_code)] #![feature(variant_count)] +#![feature(never_type)] use std::mem::variant_count; -- cgit 1.4.1-3-g733a5 From 493199626baf8a0a8f6d3a19a089165d18b3f1fb Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Wed, 24 Jun 2020 15:36:04 +0100 Subject: Fix tests --- src/libcore/mem/mod.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libcore') diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs index 2be105e68eb..1bd7ae3a34e 100644 --- a/src/libcore/mem/mod.rs +++ b/src/libcore/mem/mod.rs @@ -1010,6 +1010,7 @@ pub const fn discriminant(v: &T) -> Discriminant { /// /// ``` /// # #![feature(never_type)] +/// # #![feature(variant_count)] /// /// use std::mem; /// -- cgit 1.4.1-3-g733a5