Skip to content

Commit 6849985

Browse files
committed
Move type of discriminant to AdtDef
Previously AdtDef variants contained ConstInt for each discriminant, which did not really reflect the actual type of the discriminants. Moving the type into AdtDef allows to easily put the type into metadata and also saves bytes from ConstVal overhead for each discriminant. Also arguably the code is cleaner now :)
1 parent caf9f95 commit 6849985

File tree

10 files changed

+99
-132
lines changed

10 files changed

+99
-132
lines changed

src/librustc/ty/context.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,9 +672,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
672672
pub fn alloc_adt_def(self,
673673
did: DefId,
674674
kind: AdtKind,
675+
discr_ty: Option<attr::IntType>,
675676
variants: Vec<ty::VariantDef>)
676677
-> &'gcx ty::AdtDef {
677-
let def = ty::AdtDef::new(self, did, kind, variants);
678+
let discr_ty = discr_ty.unwrap_or(attr::UnsignedInt(ast::UintTy::U8));
679+
let def = ty::AdtDef::new(self, did, kind, discr_ty, variants);
678680
self.global_arenas.adt_def.alloc(def)
679681
}
680682

src/librustc/ty/layout.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use ty::{self, Ty, TyCtxt, TypeFoldable};
2020
use syntax::ast::{FloatTy, IntTy, UintTy};
2121
use syntax::attr;
2222
use syntax_pos::DUMMY_SP;
23-
use rustc_const_math::ConstInt;
2423

2524
use std::cmp;
2625
use std::fmt;
@@ -1207,10 +1206,12 @@ impl<'a, 'gcx, 'tcx> Layout {
12071206
i64::min_value(),
12081207
true);
12091208
for v in &def.variants {
1210-
let x = match v.disr_val.erase_type() {
1211-
ConstInt::InferSigned(i) => i as i64,
1212-
ConstInt::Infer(i) => i as u64 as i64,
1213-
_ => bug!()
1209+
let x = match def.discr_ty {
1210+
attr::IntType::SignedInt(IntTy::I128) |
1211+
attr::IntType::UnsignedInt(UintTy::U128) =>
1212+
bug!("128-bit discriminants not yet supported"),
1213+
attr::IntType::SignedInt(_) => v.disr_val as i64,
1214+
attr::IntType::UnsignedInt(_) => v.disr_val as u64 as i64,
12141215
};
12151216
if x == 0 { non_zero = false; }
12161217
if x < min { min = x; }
@@ -1271,7 +1272,7 @@ impl<'a, 'gcx, 'tcx> Layout {
12711272
// non-empty body, explicit discriminants should have
12721273
// been rejected by a checker before this point.
12731274
for (i, v) in def.variants.iter().enumerate() {
1274-
if i as u128 != v.disr_val.to_u128_unchecked() {
1275+
if i as u128 != v.disr_val {
12751276
bug!("non-C-like enum {} with specified discriminants",
12761277
tcx.item_path_str(def.did));
12771278
}

src/librustc/ty/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ use syntax::attr;
4545
use syntax::symbol::{Symbol, InternedString};
4646
use syntax_pos::{DUMMY_SP, Span};
4747

48-
use rustc_const_math::ConstInt;
4948
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
5049

5150
use hir;
@@ -72,6 +71,8 @@ pub use self::context::{Lift, TypeckTables};
7271

7372
pub use self::trait_def::{TraitDef, TraitFlags};
7473

74+
use rustc_i128::u128;
75+
7576
pub mod adjustment;
7677
pub mod cast;
7778
pub mod error;
@@ -96,7 +97,7 @@ mod flags;
9697
mod structural_impls;
9798
mod sty;
9899

99-
pub type Disr = ConstInt;
100+
pub type Disr = u128;
100101

101102
// Data types
102103

@@ -1325,6 +1326,7 @@ pub struct FieldDef {
13251326
/// table.
13261327
pub struct AdtDef {
13271328
pub did: DefId,
1329+
pub discr_ty: attr::IntType, // Type of the discriminant
13281330
pub variants: Vec<VariantDef>,
13291331
destructor: Cell<Option<DefId>>,
13301332
flags: Cell<AdtFlags>
@@ -1360,6 +1362,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
13601362
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
13611363
did: DefId,
13621364
kind: AdtKind,
1365+
discr_ty: attr::IntType,
13631366
variants: Vec<VariantDef>) -> Self {
13641367
let mut flags = AdtFlags::NO_ADT_FLAGS;
13651368
let attrs = tcx.get_attrs(did);
@@ -1382,6 +1385,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
13821385
}
13831386
AdtDef {
13841387
did: did,
1388+
discr_ty: discr_ty,
13851389
variants: variants,
13861390
flags: Cell::new(flags),
13871391
destructor: Cell::new(None),

src/librustc/ty/util.rs

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use ty::TypeVariants::*;
2323
use util::nodemap::FxHashMap;
2424
use middle::lang_items;
2525

26-
use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
26+
use rustc_const_math::ConstInt;
2727
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult};
2828

2929
use std::cell::RefCell;
@@ -34,14 +34,15 @@ use syntax::ast::{self, Name};
3434
use syntax::attr::{self, SignedInt, UnsignedInt};
3535
use syntax_pos::Span;
3636

37+
use rustc_i128::i128;
38+
3739
use hir;
3840

3941
pub trait IntTypeExt {
4042
fn to_ty<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx>;
4143
fn disr_incr<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, val: Option<Disr>)
4244
-> Option<Disr>;
43-
fn assert_ty_matches(&self, val: Disr);
44-
fn initial_discriminant<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Disr;
45+
fn initial_discriminant<'a, 'tcx>(&self, _: TyCtxt<'a, 'tcx, 'tcx>) -> Disr;
4546
}
4647

4748
impl IntTypeExt for attr::IntType {
@@ -62,56 +63,18 @@ impl IntTypeExt for attr::IntType {
6263
}
6364
}
6465

65-
fn initial_discriminant<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Disr {
66-
match *self {
67-
SignedInt(ast::IntTy::I8) => ConstInt::I8(0),
68-
SignedInt(ast::IntTy::I16) => ConstInt::I16(0),
69-
SignedInt(ast::IntTy::I32) => ConstInt::I32(0),
70-
SignedInt(ast::IntTy::I64) => ConstInt::I64(0),
71-
SignedInt(ast::IntTy::I128) => ConstInt::I128(0),
72-
SignedInt(ast::IntTy::Is) => match tcx.sess.target.int_type {
73-
ast::IntTy::I16 => ConstInt::Isize(ConstIsize::Is16(0)),
74-
ast::IntTy::I32 => ConstInt::Isize(ConstIsize::Is32(0)),
75-
ast::IntTy::I64 => ConstInt::Isize(ConstIsize::Is64(0)),
76-
_ => bug!(),
77-
},
78-
UnsignedInt(ast::UintTy::U8) => ConstInt::U8(0),
79-
UnsignedInt(ast::UintTy::U16) => ConstInt::U16(0),
80-
UnsignedInt(ast::UintTy::U32) => ConstInt::U32(0),
81-
UnsignedInt(ast::UintTy::U64) => ConstInt::U64(0),
82-
UnsignedInt(ast::UintTy::U128) => ConstInt::U128(0),
83-
UnsignedInt(ast::UintTy::Us) => match tcx.sess.target.uint_type {
84-
ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16(0)),
85-
ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32(0)),
86-
ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64(0)),
87-
_ => bug!(),
88-
},
89-
}
90-
}
91-
92-
fn assert_ty_matches(&self, val: Disr) {
93-
match (*self, val) {
94-
(SignedInt(ast::IntTy::I8), ConstInt::I8(_)) => {},
95-
(SignedInt(ast::IntTy::I16), ConstInt::I16(_)) => {},
96-
(SignedInt(ast::IntTy::I32), ConstInt::I32(_)) => {},
97-
(SignedInt(ast::IntTy::I64), ConstInt::I64(_)) => {},
98-
(SignedInt(ast::IntTy::I128), ConstInt::I128(_)) => {},
99-
(SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) => {},
100-
(UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) => {},
101-
(UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) => {},
102-
(UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) => {},
103-
(UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) => {},
104-
(UnsignedInt(ast::UintTy::U128), ConstInt::U128(_)) => {},
105-
(UnsignedInt(ast::UintTy::Us), ConstInt::Usize(_)) => {},
106-
_ => bug!("disr type mismatch: {:?} vs {:?}", self, val),
107-
}
66+
fn initial_discriminant<'a, 'tcx>(&self, _: TyCtxt<'a, 'tcx, 'tcx>) -> Disr {
67+
0
10868
}
10969

70+
/// None = overflow
11071
fn disr_incr<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, val: Option<Disr>)
111-
-> Option<Disr> {
72+
-> Option<Disr> {
11273
if let Some(val) = val {
113-
self.assert_ty_matches(val);
114-
(val + ConstInt::Infer(1)).ok()
74+
match *self {
75+
SignedInt(it) => ConstInt::new_signed(val as i128, it, tcx.sess.target.int_type),
76+
UnsignedInt(it) => ConstInt::new_unsigned(val, it, tcx.sess.target.uint_type),
77+
}.and_then(|l| (l + ConstInt::Infer(1)).ok()).map(|v| v.to_u128_unchecked())
11578
} else {
11679
Some(self.initial_discriminant(tcx))
11780
}

src/librustc_metadata/decoder.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ use rustc::session::Session;
2525
use rustc::ty::{self, Ty, TyCtxt};
2626
use rustc::ty::subst::Substs;
2727

28-
use rustc_const_math::ConstInt;
29-
3028
use rustc::mir::Mir;
3129

3230
use std::borrow::Cow;
@@ -435,7 +433,7 @@ impl<'tcx> EntryKind<'tcx> {
435433
EntryKind::Mod(_) => Def::Mod(did),
436434
EntryKind::Variant(_) => Def::Variant(did),
437435
EntryKind::Trait(_) => Def::Trait(did),
438-
EntryKind::Enum => Def::Enum(did),
436+
EntryKind::Enum(_) => Def::Enum(did),
439437
EntryKind::MacroDef(_) => Def::Macro(did),
440438

441439
EntryKind::ForeignMod |
@@ -535,7 +533,7 @@ impl<'a, 'tcx> CrateMetadata {
535533
vis: f.visibility.decode(self)
536534
}
537535
}).collect(),
538-
disr_val: ConstInt::Infer(data.disr),
536+
disr_val: data.disr,
539537
ctor_kind: data.ctor_kind,
540538
}, data.struct_ctor)
541539
}
@@ -546,8 +544,14 @@ impl<'a, 'tcx> CrateMetadata {
546544
-> &'tcx ty::AdtDef {
547545
let item = self.entry(item_id);
548546
let did = self.local_def_id(item_id);
547+
let (kind, ty) = match item.kind {
548+
EntryKind::Enum(dt) => (ty::AdtKind::Enum, Some(dt.decode(self))),
549+
EntryKind::Struct(_) => (ty::AdtKind::Struct, None),
550+
EntryKind::Union(_) => (ty::AdtKind::Union, None),
551+
_ => bug!("get_adt_def called on a non-ADT {:?}", did),
552+
};
549553
let mut ctor_index = None;
550-
let variants = if let EntryKind::Enum = item.kind {
554+
let variants = if let ty::AdtKind::Enum = kind {
551555
item.children
552556
.decode(self)
553557
.map(|index| {
@@ -561,14 +565,8 @@ impl<'a, 'tcx> CrateMetadata {
561565
ctor_index = struct_ctor;
562566
vec![variant]
563567
};
564-
let kind = match item.kind {
565-
EntryKind::Enum => ty::AdtKind::Enum,
566-
EntryKind::Struct(_) => ty::AdtKind::Struct,
567-
EntryKind::Union(_) => ty::AdtKind::Union,
568-
_ => bug!("get_adt_def called on a non-ADT {:?}", did),
569-
};
570568

571-
let adt = tcx.alloc_adt_def(did, kind, variants);
569+
let adt = tcx.alloc_adt_def(did, kind, ty, variants);
572570
if let Some(ctor_index) = ctor_index {
573571
// Make adt definition available through constructor id as well.
574572
tcx.adt_defs.borrow_mut().insert(self.local_def_id(ctor_index), adt);

src/librustc_metadata/encoder.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
261261

262262
let data = VariantData {
263263
ctor_kind: variant.ctor_kind,
264-
disr: variant.disr_val.to_u128_unchecked(),
264+
disr: variant.disr_val,
265265
struct_ctor: None,
266266
};
267267

@@ -388,7 +388,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
388388

389389
let data = VariantData {
390390
ctor_kind: variant.ctor_kind,
391-
disr: variant.disr_val.to_u128_unchecked(),
391+
disr: variant.disr_val,
392392
struct_ctor: Some(def_id.index),
393393
};
394394

@@ -659,7 +659,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
659659
}
660660
hir::ItemForeignMod(_) => EntryKind::ForeignMod,
661661
hir::ItemTy(..) => EntryKind::Type,
662-
hir::ItemEnum(..) => EntryKind::Enum,
662+
hir::ItemEnum(..) => EntryKind::Enum(self.lazy(&tcx.lookup_adt_def(def_id).discr_ty)),
663663
hir::ItemStruct(ref struct_def, _) => {
664664
let variant = tcx.lookup_adt_def(def_id).struct_variant();
665665

@@ -673,7 +673,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
673673
};
674674
EntryKind::Struct(self.lazy(&VariantData {
675675
ctor_kind: variant.ctor_kind,
676-
disr: variant.disr_val.to_u128_unchecked(),
676+
disr: variant.disr_val,
677677
struct_ctor: struct_ctor,
678678
}))
679679
}
@@ -682,7 +682,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
682682

683683
EntryKind::Union(self.lazy(&VariantData {
684684
ctor_kind: variant.ctor_kind,
685-
disr: variant.disr_val.to_u128_unchecked(),
685+
disr: variant.disr_val,
686686
struct_ctor: None,
687687
}))
688688
}

src/librustc_metadata/schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ pub enum EntryKind<'tcx> {
228228
ForeignMutStatic,
229229
ForeignMod,
230230
Type,
231-
Enum,
231+
Enum(Lazy<attr::IntType>),
232232
Field,
233233
Variant(Lazy<VariantData>),
234234
Struct(Lazy<VariantData>),

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14731473
DIB(cx),
14741474
name.as_ptr(),
14751475
// FIXME: what if enumeration has i128 discriminant?
1476-
v.disr_val.to_u128_unchecked() as u64)
1476+
v.disr_val as u64)
14771477
}
14781478
})
14791479
.collect();

src/librustc_trans/disr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl ::std::ops::BitAnd for Disr {
2727
impl From<::rustc::ty::Disr> for Disr {
2828
fn from(i: ::rustc::ty::Disr) -> Disr {
2929
// FIXME: what if discr has 128 bit discr?
30-
Disr(i.to_u128_unchecked() as u64)
30+
Disr(i as u64)
3131
}
3232
}
3333

0 commit comments

Comments
 (0)