From dea9c47ac08fd9cd169741d14e6fa323b1025426 Mon Sep 17 00:00:00 2001 From: Kevin Murphy Date: Wed, 30 Apr 2014 03:11:45 -0700 Subject: [PATCH] Add num_variants intrinsic for enums and safe wrapper in std::reflect --- src/librustc/middle/trans/intrinsic.rs | 11 +++++++++++ src/librustc/middle/typeck/check/mod.rs | 1 + src/libstd/intrinsics.rs | 4 ++++ src/libstd/reflect.rs | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index 86fde5d821a00..9288efaba0dd7 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -323,6 +323,17 @@ pub fn trans_intrinsic(ccx: &CrateContext, let lltp_ty = type_of::type_of(ccx, tp_ty); Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty) as uint)); } + "num_variants" => { + let tp_ty = *substs.tys.get(0); + let ref sty = ty::get(tp_ty).sty; + let num_variants = match *sty { + ty::ty_enum(did, _) => { + ty::enum_variants(ccx.tcx(), did).len() + } + _ => 0 + }; + Ret(bcx, C_uint(ccx, num_variants)); + } "get_tydesc" => { let tp_ty = *substs.tys.get(0); let static_ti = get_tydesc(ccx, tp_ty); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a0847baaea285..e8f57652ae6a0 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -4139,6 +4139,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { } "needs_drop" => (1u, Vec::new(), ty::mk_bool()), "owns_managed" => (1u, Vec::new(), ty::mk_bool()), + "num_variants" => (1u, Vec::new(), ty::mk_uint()), "get_tydesc" => { let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) { diff --git a/src/libstd/intrinsics.rs b/src/libstd/intrinsics.rs index 09cdad943057b..afc333f8c660c 100644 --- a/src/libstd/intrinsics.rs +++ b/src/libstd/intrinsics.rs @@ -280,6 +280,10 @@ extern "rust-intrinsic" { pub fn min_align_of() -> uint; pub fn pref_align_of() -> uint; + /// Gets the number of variants in an enum + #[cfg(not(stage0))] + pub fn num_variants() -> uint; + /// Get a static pointer to a type descriptor. pub fn get_tydesc() -> *TyDesc; diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index 45f214e26fb2e..0f3a30267db5b 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -37,6 +37,14 @@ pub fn align(size: uint, align: uint) -> uint { ((size + align) - 1u) & !(align - 1u) } +/// Get the number of variants in an enum +#[cfg(not(stage0))] +#[inline] +pub fn num_variants() -> uint { + use intrinsics::num_variants; + unsafe { num_variants::() } +} + /// Adaptor to wrap around visitors implementing MovePtr. pub struct MovePtrAdaptor { inner: V