Skip to content

Commit a8075a4

Browse files
committed
AdtDef now contains discr_ty same as layouted
1 parent 6849985 commit a8075a4

File tree

5 files changed

+39
-17
lines changed

5 files changed

+39
-17
lines changed

src/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc/ty/layout.rs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,23 @@ impl Integer {
382382
}
383383
}
384384

385+
pub fn to_attr(&self, signed: bool) -> attr::IntType {
386+
match (*self, signed) {
387+
(I1, false) => attr::IntType::UnsignedInt(UintTy::U8),
388+
(I8, false) => attr::IntType::UnsignedInt(UintTy::U8),
389+
(I16, false) => attr::IntType::UnsignedInt(UintTy::U16),
390+
(I32, false) => attr::IntType::UnsignedInt(UintTy::U32),
391+
(I64, false) => attr::IntType::UnsignedInt(UintTy::U64),
392+
(I128, false) => attr::IntType::UnsignedInt(UintTy::U128),
393+
(I1, true) => attr::IntType::SignedInt(IntTy::I8),
394+
(I8, true) => attr::IntType::SignedInt(IntTy::I8),
395+
(I16, true) => attr::IntType::SignedInt(IntTy::I16),
396+
(I32, true) => attr::IntType::SignedInt(IntTy::I32),
397+
(I64, true) => attr::IntType::SignedInt(IntTy::I64),
398+
(I128, true) => attr::IntType::SignedInt(IntTy::I128),
399+
}
400+
}
401+
385402
/// Find the smallest Integer type which can represent the signed value.
386403
pub fn fit_signed(x: i64) -> Integer {
387404
match x {
@@ -436,13 +453,13 @@ impl Integer {
436453
/// signed discriminant range and #[repr] attribute.
437454
/// N.B.: u64 values above i64::MAX will be treated as signed, but
438455
/// that shouldn't affect anything, other than maybe debuginfo.
439-
fn repr_discr(tcx: TyCtxt, ty: Ty, hints: &[attr::ReprAttr], min: i64, max: i64)
440-
-> (Integer, bool) {
456+
pub fn repr_discr(tcx: TyCtxt, hints: &[attr::ReprAttr], min: i128, max: i128)
457+
-> (Integer, bool) {
441458
// Theoretically, negative values could be larger in unsigned representation
442459
// than the unsigned representation of the signed minimum. However, if there
443460
// are any negative values, the only valid unsigned representation is u64
444461
// which can fit all i64 values, so the result remains unaffected.
445-
let unsigned_fit = Integer::fit_unsigned(cmp::max(min as u64, max as u64));
462+
let unsigned_fit = Integer::fit_unsigned(cmp::max(min as u128, max as u128));
446463
let signed_fit = cmp::max(Integer::fit_signed(min), Integer::fit_signed(max));
447464

448465
let mut min_from_extern = None;
@@ -455,7 +472,7 @@ impl Integer {
455472
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
456473
if discr < fit {
457474
bug!("Integer::repr_discr: `#[repr]` hint too small for \
458-
discriminant range of enum `{}", ty)
475+
discriminant range of enum")
459476
}
460477
return (discr, ity.is_signed());
461478
}
@@ -471,16 +488,15 @@ impl Integer {
471488
}
472489
attr::ReprAny => {},
473490
attr::ReprPacked => {
474-
bug!("Integer::repr_discr: found #[repr(packed)] on enum `{}", ty);
491+
bug!("Integer::repr_discr: found #[repr(packed)] on enum");
475492
}
476493
attr::ReprSimd => {
477-
bug!("Integer::repr_discr: found #[repr(simd)] on enum `{}", ty);
494+
bug!("Integer::repr_discr: found #[repr(simd)] on enum");
478495
}
479496
}
480497
}
481498

482499
let at_least = min_from_extern.unwrap_or(min_default);
483-
484500
// If there are no negative values, we can use the unsigned fit.
485501
if min >= 0 {
486502
(cmp::max(unsigned_fit, at_least), false)
@@ -1220,9 +1236,8 @@ impl<'a, 'gcx, 'tcx> Layout {
12201236

12211237
// FIXME: should handle i128? signed-value based impl is weird and hard to
12221238
// grok.
1223-
let (discr, signed) = Integer::repr_discr(tcx, ty, &hints[..],
1224-
min,
1225-
max);
1239+
let discr = Integer::from_attr(&tcx.data_layout, def.discr_ty);
1240+
let signed = def.discr_ty.is_signed();
12261241
return success(CEnum {
12271242
discr: discr,
12281243
signed: signed,
@@ -1337,10 +1352,7 @@ impl<'a, 'gcx, 'tcx> Layout {
13371352
}
13381353

13391354
// The general case.
1340-
let discr_max = (variants.len() - 1) as i64;
1341-
assert!(discr_max >= 0);
1342-
let (min_ity, _) = Integer::repr_discr(tcx, ty, &hints[..], 0, discr_max);
1343-
1355+
let min_ity = Integer::from_attr(&tcx.data_layout, def.discr_ty);
13441356
let mut align = dl.aggregate_align;
13451357
let mut size = Size::from_bytes(0);
13461358

src/librustc_typeck/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ rustc_data_structures = { path = "../librustc_data_structures" }
2222
rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
2323
syntax_pos = { path = "../libsyntax_pos" }
2424
rustc_errors = { path = "../librustc_errors" }
25+
rustc_i128 = { path = "../librustc_i128" }

src/librustc_typeck/collect.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use rustc_const_eval::EvalHint::UncheckedExprHint;
6666
use rustc_const_eval::{ConstContext, report_const_eval_err};
6767
use rustc::ty::subst::Substs;
6868
use rustc::ty::{ToPredicate, ImplContainer, AssociatedItemContainer, TraitContainer};
69-
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
69+
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt, layout};
7070
use rustc::ty::util::IntTypeExt;
7171
use rustc::dep_graph::DepNode;
7272
use util::common::{ErrorReported, MemoizationMap};
@@ -86,6 +86,8 @@ use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
8686
use rustc::hir::def::{Def, CtorKind};
8787
use rustc::hir::def_id::DefId;
8888

89+
use rustc_i128::i128;
90+
8991
///////////////////////////////////////////////////////////////////////////
9092
// Main entry point
9193

@@ -1090,9 +1092,11 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
10901092
let repr_type = tcx.enum_repr_type(repr_hints.get(0));
10911093
let initial = repr_type.initial_discriminant(tcx);
10921094
let mut prev_disr = None::<ty::Disr>;
1095+
let (mut min, mut max) = (i128::max_value(), i128::min_value());
10931096
let variants = def.variants.iter().map(|v| {
10941097
let wrapped_disr = prev_disr.map_or(initial, |d| d.wrapping_add(1));
10951098
let disr = if let Some(e) = v.node.disr_expr {
1099+
// FIXME: i128 discriminants
10961100
evaluate_disr_expr(ccx, repr_type, e)
10971101
} else if let Some(disr) = repr_type.disr_incr(tcx, prev_disr) {
10981102
Some(disr)
@@ -1106,12 +1110,14 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
11061110
None
11071111
}.unwrap_or(wrapped_disr);
11081112
prev_disr = Some(disr);
1109-
1113+
if (disr as i128) < min { min = disr as i128; }
1114+
if (disr as i128) > max { max = disr as i128; }
11101115
let did = tcx.hir.local_def_id(v.node.data.id());
11111116
convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
11121117
}).collect();
11131118

1114-
let adt = tcx.alloc_adt_def(did, AdtKind::Enum, Some(repr_type), variants);
1119+
let (repr_int, signed) = layout::Integer::repr_discr(tcx, &repr_hints[..], min, max);
1120+
let adt = tcx.alloc_adt_def(did, AdtKind::Enum, Some(repr_int.to_attr(signed)), variants);
11151121
tcx.adt_defs.borrow_mut().insert(did, adt);
11161122
adt
11171123
}

src/librustc_typeck/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ extern crate rustc_const_eval;
9898
extern crate rustc_data_structures;
9999
extern crate rustc_errors as errors;
100100

101+
extern crate rustc_i128;
102+
101103
pub use rustc::dep_graph;
102104
pub use rustc::hir;
103105
pub use rustc::lint;

0 commit comments

Comments
 (0)