diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 0e91eafce187..80f506ebc064 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -569,4 +569,10 @@ extern "rust-intrinsic" { pub fn overflowing_sub(a: T, b: T) -> T; /// Returns (a * b) mod 2^N, where N is the width of N in bits. pub fn overflowing_mul(a: T, b: T) -> T; + + /// Returns the value of the discriminant for the variant in 'v', + /// cast to a `u64`; if `T` has no discriminant, returns 0. + // SNAP 5520801 + #[cfg(not(stage0))] + pub fn discriminant_value(v: &T) -> u64; } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 62a6ede4c2f9..fc3c0841dd84 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -14,6 +14,7 @@ use llvm; use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind}; use middle::subst; use middle::subst::FnSpace; +use trans::adt; use trans::base::*; use trans::build::*; use trans::callee; @@ -683,6 +684,17 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } } + (_, "discriminant_value") => { + let val_ty = substs.types.get(FnSpace, 0); + match val_ty.sty { + ty::ty_enum(..) => { + let repr = adt::represent_type(ccx, *val_ty); + adt::trans_get_discr(bcx, &*repr, llargs[0], Some(llret_ty)) + } + _ => C_null(llret_ty) + } + } + // This requires that atomic intrinsics follow a specific naming pattern: // "atomic_[_]", and no ordering means SeqCst (_, name) if name.starts_with("atomic_") => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f7bbc693ce59..31039e3abca6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5073,6 +5073,12 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "assume" => (0, vec![tcx.types.bool], ty::mk_nil(tcx)), + "discriminant_value" => (1, vec![ + ty::mk_imm_rptr(tcx, + tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), + ty::BrAnon(0))), + param(ccx, 0))], tcx.types.u64), + ref other => { span_err!(tcx.sess, it.span, E0093, "unrecognized intrinsic function: `{}`", *other);