Skip to content

Commit 41dd355

Browse files
Aatchpnkfelix
authored andcommitted
Implement discriminant_value intrinsic
Implements an intrinsic for extracting the value of the discriminant enum variant values. For non-enum types, this returns zero, otherwise it returns the value we use for discriminant comparisons. This means that enum types that do not have a discriminant will also work in this arrangement. This is (at least part of) the work on Issue rust-lang#24263
1 parent 6b95d8b commit 41dd355

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

src/libcore/intrinsics.rs

+6
Original file line numberDiff line numberDiff line change
@@ -569,4 +569,10 @@ extern "rust-intrinsic" {
569569
pub fn overflowing_sub<T>(a: T, b: T) -> T;
570570
/// Returns (a * b) mod 2^N, where N is the width of N in bits.
571571
pub fn overflowing_mul<T>(a: T, b: T) -> T;
572+
573+
/// Returns the value of the discriminant for the variant in 'v',
574+
/// cast to a `u64`; if `T` has no discriminant, returns 0.
575+
// SNAP 5520801
576+
#[cfg(not(stage0))]
577+
pub fn discriminant_value<T>(v: &T) -> u64;
572578
}

src/librustc_trans/trans/intrinsic.rs

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use llvm;
1414
use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind};
1515
use middle::subst;
1616
use middle::subst::FnSpace;
17+
use trans::adt;
1718
use trans::base::*;
1819
use trans::build::*;
1920
use trans::callee;
@@ -683,6 +684,17 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
683684
}
684685
}
685686

687+
(_, "discriminant_value") => {
688+
let val_ty = substs.types.get(FnSpace, 0);
689+
match val_ty.sty {
690+
ty::ty_enum(..) => {
691+
let repr = adt::represent_type(ccx, *val_ty);
692+
adt::trans_get_discr(bcx, &*repr, llargs[0], Some(llret_ty))
693+
}
694+
_ => C_null(llret_ty)
695+
}
696+
}
697+
686698
// This requires that atomic intrinsics follow a specific naming pattern:
687699
// "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
688700
(_, name) if name.starts_with("atomic_") => {

src/librustc_typeck/check/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -5073,6 +5073,12 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
50735073

50745074
"assume" => (0, vec![tcx.types.bool], ty::mk_nil(tcx)),
50755075

5076+
"discriminant_value" => (1, vec![
5077+
ty::mk_imm_rptr(tcx,
5078+
tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1),
5079+
ty::BrAnon(0))),
5080+
param(ccx, 0))], tcx.types.u64),
5081+
50765082
ref other => {
50775083
span_err!(tcx.sess, it.span, E0093,
50785084
"unrecognized intrinsic function: `{}`", *other);

0 commit comments

Comments
 (0)