1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use rustc::middle::const_val::ConstVal;
use rustc::ty::{self, TyCtxt};
use rustc_const_math::ConstInt;
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub struct Disr(pub u64);
impl Disr {
pub fn for_variant(tcx: TyCtxt,
def: &ty::AdtDef,
variant_index: usize) -> Self {
let mut explicit_index = variant_index;
let mut explicit_value = Disr(0);
loop {
match def.variants[explicit_index].discr {
ty::VariantDiscr::Relative(0) => break,
ty::VariantDiscr::Relative(distance) => {
explicit_index -= distance;
}
ty::VariantDiscr::Explicit(expr_did) => {
match tcx.maps.monomorphic_const_eval.borrow()[&expr_did] {
Ok(ConstVal::Integral(v)) => {
explicit_value = Disr::from(v);
break;
}
_ => {
explicit_index -= 1;
}
}
}
}
}
let distance = variant_index - explicit_index;
explicit_value.wrapping_add(Disr::from(distance))
}
pub fn wrapping_add(self, other: Self) -> Self {
Disr(self.0.wrapping_add(other.0))
}
}
impl ::std::ops::BitAnd for Disr {
type Output = Disr;
fn bitand(self, other: Self) -> Self {
Disr(self.0 & other.0)
}
}
impl From<ConstInt> for Disr {
fn from(i: ConstInt) -> Disr {
Disr(i.to_u128_unchecked() as u64)
}
}
impl From<usize> for Disr {
fn from(i: usize) -> Disr {
Disr(i as u64)
}
}
impl PartialOrd for Disr {
fn partial_cmp(&self, other: &Disr) -> Option<::std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl Ord for Disr {
fn cmp(&self, other: &Disr) -> ::std::cmp::Ordering {
self.0.cmp(&other.0)
}
}