Skip to content

Commit 91d76b0

Browse files
committed
rustc: intern ConstVal's in TyCtxt.
1 parent f861b6e commit 91d76b0

File tree

31 files changed

+347
-240
lines changed

31 files changed

+347
-240
lines changed

src/librustc/hir/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ pub enum BindingAnnotation {
611611
RefMut,
612612
}
613613

614-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
614+
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
615615
pub enum RangeEnd {
616616
Included,
617617
Excluded,

src/librustc/ich/impls_ty.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
1616
StableHasherResult};
1717
use std::hash as std_hash;
1818
use std::mem;
19-
use syntax_pos::symbol::InternedString;
2019
use ty;
2120

2221
impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
@@ -271,59 +270,60 @@ for ::middle::const_val::ConstVal<'gcx> {
271270
fn hash_stable<W: StableHasherResult>(&self,
272271
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
273272
hasher: &mut StableHasher<W>) {
274-
use middle::const_val::ConstVal;
273+
use middle::const_val::ConstVal::*;
274+
use middle::const_val::ConstAggregate::*;
275275

276276
mem::discriminant(self).hash_stable(hcx, hasher);
277277

278278
match *self {
279-
ConstVal::Float(ref value) => {
279+
Float(ref value) => {
280280
value.hash_stable(hcx, hasher);
281281
}
282-
ConstVal::Integral(ref value) => {
282+
Integral(ref value) => {
283283
value.hash_stable(hcx, hasher);
284284
}
285-
ConstVal::Str(ref value) => {
285+
Str(ref value) => {
286286
value.hash_stable(hcx, hasher);
287287
}
288-
ConstVal::ByteStr(ref value) => {
288+
ByteStr(ref value) => {
289289
value.hash_stable(hcx, hasher);
290290
}
291-
ConstVal::Bool(value) => {
291+
Bool(value) => {
292292
value.hash_stable(hcx, hasher);
293293
}
294-
ConstVal::Char(value) => {
294+
Char(value) => {
295295
value.hash_stable(hcx, hasher);
296296
}
297-
ConstVal::Variant(def_id) => {
297+
Variant(def_id) => {
298298
def_id.hash_stable(hcx, hasher);
299299
}
300-
ConstVal::Function(def_id, substs) => {
300+
Function(def_id, substs) => {
301301
def_id.hash_stable(hcx, hasher);
302302
substs.hash_stable(hcx, hasher);
303303
}
304-
ConstVal::Struct(ref name_value_map) => {
305-
let mut values: Vec<(InternedString, &ConstVal)> =
306-
name_value_map.iter()
307-
.map(|(name, val)| (name.as_str(), val))
308-
.collect();
309-
304+
Aggregate(Struct(ref name_values)) => {
305+
let mut values = name_values.to_vec();
310306
values.sort_unstable_by_key(|&(ref name, _)| name.clone());
311307
values.hash_stable(hcx, hasher);
312308
}
313-
ConstVal::Tuple(ref value) => {
309+
Aggregate(Tuple(ref value)) => {
314310
value.hash_stable(hcx, hasher);
315311
}
316-
ConstVal::Array(ref value) => {
312+
Aggregate(Array(ref value)) => {
317313
value.hash_stable(hcx, hasher);
318314
}
319-
ConstVal::Repeat(ref value, times) => {
315+
Aggregate(Repeat(ref value, times)) => {
320316
value.hash_stable(hcx, hasher);
321317
times.hash_stable(hcx, hasher);
322318
}
323319
}
324320
}
325321
}
326322

323+
impl_stable_hash_for!(struct ::middle::const_val::ByteArray<'tcx> {
324+
data
325+
});
326+
327327
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
328328

329329
impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness });

src/librustc/middle/const_val.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use self::ConstVal::*;
12+
use self::ConstAggregate::*;
1213
pub use rustc_const_math::ConstInt;
1314

1415
use hir;
@@ -22,30 +23,55 @@ use rustc_const_math::*;
2223

2324
use graphviz::IntoCow;
2425
use errors::DiagnosticBuilder;
26+
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
2527
use syntax::symbol::InternedString;
2628
use syntax::ast;
2729
use syntax_pos::Span;
2830

2931
use std::borrow::Cow;
30-
use std::collections::BTreeMap;
31-
use std::rc::Rc;
3232

33-
pub type EvalResult<'tcx> = Result<ConstVal<'tcx>, ConstEvalErr<'tcx>>;
33+
pub type EvalResult<'tcx> = Result<&'tcx ConstVal<'tcx>, ConstEvalErr<'tcx>>;
3434

35-
#[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
35+
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
3636
pub enum ConstVal<'tcx> {
3737
Float(ConstFloat),
3838
Integral(ConstInt),
3939
Str(InternedString),
40-
ByteStr(Rc<Vec<u8>>),
40+
ByteStr(ByteArray<'tcx>),
4141
Bool(bool),
4242
Char(char),
4343
Variant(DefId),
4444
Function(DefId, &'tcx Substs<'tcx>),
45-
Struct(BTreeMap<ast::Name, ConstVal<'tcx>>),
46-
Tuple(Vec<ConstVal<'tcx>>),
47-
Array(Vec<ConstVal<'tcx>>),
48-
Repeat(Box<ConstVal<'tcx>>, u64),
45+
Aggregate(ConstAggregate<'tcx>),
46+
}
47+
48+
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx ConstVal<'tcx> {}
49+
50+
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, Eq, PartialEq)]
51+
pub struct ByteArray<'tcx> {
52+
pub data: &'tcx [u8],
53+
}
54+
55+
impl<'tcx> serialize::UseSpecializedDecodable for ByteArray<'tcx> {}
56+
57+
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
58+
pub enum ConstAggregate<'tcx> {
59+
Struct(&'tcx [(ast::Name, &'tcx ConstVal<'tcx>)]),
60+
Tuple(&'tcx [&'tcx ConstVal<'tcx>]),
61+
Array(&'tcx [&'tcx ConstVal<'tcx>]),
62+
Repeat(&'tcx ConstVal<'tcx>, u64),
63+
}
64+
65+
impl<'tcx> Encodable for ConstAggregate<'tcx> {
66+
fn encode<S: Encoder>(&self, _: &mut S) -> Result<(), S::Error> {
67+
bug!("should never encode ConstAggregate::{:?}", self)
68+
}
69+
}
70+
71+
impl<'tcx> Decodable for ConstAggregate<'tcx> {
72+
fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
73+
bug!("should never decode ConstAggregate")
74+
}
4975
}
5076

5177
impl<'tcx> ConstVal<'tcx> {
@@ -58,11 +84,11 @@ impl<'tcx> ConstVal<'tcx> {
5884
Bool(_) => "boolean",
5985
Char(..) => "char",
6086
Variant(_) => "enum variant",
61-
Struct(_) => "struct",
62-
Tuple(_) => "tuple",
87+
Aggregate(Struct(_)) => "struct",
88+
Aggregate(Tuple(_)) => "tuple",
6389
Function(..) => "function definition",
64-
Array(..) => "array",
65-
Repeat(..) => "repeat",
90+
Aggregate(Array(..)) => "array",
91+
Aggregate(Repeat(..)) => "repeat",
6692
}
6793
}
6894

@@ -233,7 +259,7 @@ pub fn eval_length(tcx: TyCtxt,
233259
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
234260
let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id);
235261
match tcx.at(count_expr.span).const_eval(param_env.and((count_def_id, substs))) {
236-
Ok(Integral(Usize(count))) => {
262+
Ok(&Integral(Usize(count))) => {
237263
let val = count.as_u64(tcx.sess.target.uint_type);
238264
assert_eq!(val as usize as u64, val);
239265
Ok(val as usize)

src/librustc/mir/mod.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,9 @@ impl<'tcx> Operand<'tcx> {
11901190
Operand::Constant(box Constant {
11911191
span,
11921192
ty: tcx.type_of(def_id).subst(tcx, substs),
1193-
literal: Literal::Value { value: ConstVal::Function(def_id, substs) },
1193+
literal: Literal::Value {
1194+
value: tcx.mk_const(ConstVal::Function(def_id, substs))
1195+
},
11941196
})
11951197
}
11961198

@@ -1482,7 +1484,7 @@ pub enum Literal<'tcx> {
14821484
substs: &'tcx Substs<'tcx>,
14831485
},
14841486
Value {
1485-
value: ConstVal<'tcx>,
1487+
value: &'tcx ConstVal<'tcx>,
14861488
},
14871489
Promoted {
14881490
// Index into the `promoted` vector of `Mir`.
@@ -1520,9 +1522,9 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
15201522
match *const_val {
15211523
Float(f) => write!(fmt, "{:?}", f),
15221524
Integral(n) => write!(fmt, "{}", n),
1523-
Str(ref s) => write!(fmt, "{:?}", s),
1524-
ByteStr(ref bytes) => {
1525-
let escaped: String = bytes
1525+
Str(s) => write!(fmt, "{:?}", s),
1526+
ByteStr(bytes) => {
1527+
let escaped: String = bytes.data
15261528
.iter()
15271529
.flat_map(|&ch| ascii::escape_default(ch).map(|c| c as char))
15281530
.collect();
@@ -1532,8 +1534,7 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
15321534
Char(c) => write!(fmt, "{:?}", c),
15331535
Variant(def_id) |
15341536
Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
1535-
Struct(_) | Tuple(_) | Array(_) | Repeat(..) =>
1536-
bug!("ConstVal `{:?}` should not be in MIR", const_val),
1537+
Aggregate(_) => bug!("`ConstVal::{:?}` should not be in MIR", const_val),
15371538
}
15381539
}
15391540

src/librustc/mir/visit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ macro_rules! make_mir_visitor {
233233
}
234234

235235
fn visit_const_val(&mut self,
236-
const_val: & $($mutability)* ConstVal,
236+
const_val: & $($mutability)* &'tcx ConstVal<'tcx>,
237237
_: Location) {
238238
self.super_const_val(const_val);
239239
}
@@ -758,7 +758,7 @@ macro_rules! make_mir_visitor {
758758
_substs: & $($mutability)* ClosureSubsts<'tcx>) {
759759
}
760760

761-
fn super_const_val(&mut self, _const_val: & $($mutability)* ConstVal) {
761+
fn super_const_val(&mut self, _const_val: & $($mutability)* &'tcx ConstVal<'tcx>) {
762762
}
763763

764764
fn super_const_int(&mut self, _const_int: &ConstInt) {

src/librustc/ty/context.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use hir::map as hir_map;
2121
use hir::map::DefPathHash;
2222
use lint::{self, Lint};
2323
use ich::{self, StableHashingContext, NodeIdHashingMode};
24+
use middle::const_val::ConstVal;
2425
use middle::free_region::FreeRegionMap;
2526
use middle::lang_items;
2627
use middle::resolve_lifetime;
@@ -109,6 +110,7 @@ pub struct CtxtInterners<'tcx> {
109110
region: RefCell<FxHashSet<Interned<'tcx, RegionKind>>>,
110111
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
111112
predicates: RefCell<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>,
113+
const_: RefCell<FxHashSet<Interned<'tcx, ConstVal<'tcx>>>>,
112114
}
113115

114116
impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
@@ -121,6 +123,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
121123
region: RefCell::new(FxHashSet()),
122124
existential_predicates: RefCell::new(FxHashSet()),
123125
predicates: RefCell::new(FxHashSet()),
126+
const_: RefCell::new(FxHashSet()),
124127
}
125128
}
126129

@@ -967,6 +970,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
967970
self.global_arenas.adt_def.alloc(def)
968971
}
969972

973+
pub fn alloc_byte_array(self, bytes: &[u8]) -> &'gcx [u8] {
974+
if bytes.is_empty() {
975+
&[]
976+
} else {
977+
self.global_interners.arena.alloc_slice(bytes)
978+
}
979+
}
980+
981+
pub fn alloc_constval_slice(self, values: &[&'tcx ConstVal<'gcx>])
982+
-> &'gcx [&'tcx ConstVal<'gcx>] {
983+
if values.is_empty() {
984+
&[]
985+
} else {
986+
self.global_interners.arena.alloc_slice(values)
987+
}
988+
}
989+
990+
pub fn alloc_name_constval_slice(self, values: &[(ast::Name, &'tcx ConstVal<'gcx>)])
991+
-> &'gcx [(ast::Name, &'tcx ConstVal<'gcx>)] {
992+
if values.is_empty() {
993+
&[]
994+
} else {
995+
self.global_interners.arena.alloc_slice(values)
996+
}
997+
}
998+
970999
pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
9711000
if let Some(st) = self.stability_interner.borrow().get(&stab) {
9721001
return st;
@@ -1493,6 +1522,12 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Predicate<'lcx>]>
14931522
}
14941523
}
14951524

1525+
impl<'tcx: 'lcx, 'lcx> Borrow<ConstVal<'lcx>> for Interned<'tcx, ConstVal<'tcx>> {
1526+
fn borrow<'a>(&'a self) -> &'a ConstVal<'lcx> {
1527+
&self.0
1528+
}
1529+
}
1530+
14961531
macro_rules! intern_method {
14971532
($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
14981533
$alloc_method:ident,
@@ -1573,7 +1608,8 @@ direct_interners!('tcx,
15731608
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
15741609
_ => false
15751610
}
1576-
}) -> RegionKind
1611+
}) -> RegionKind,
1612+
const_: mk_const(/*|c: &Const| keep_local(&c.ty)*/ |_| false) -> ConstVal<'tcx>
15771613
);
15781614

15791615
macro_rules! slice_interners {

src/librustc/ty/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
15971597
if let VariantDiscr::Explicit(expr_did) = v.discr {
15981598
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
15991599
match tcx.const_eval(param_env.and((expr_did, substs))) {
1600-
Ok(ConstVal::Integral(v)) => {
1600+
Ok(&ConstVal::Integral(v)) => {
16011601
discr = v;
16021602
}
16031603
err => {
@@ -1637,7 +1637,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
16371637
ty::VariantDiscr::Explicit(expr_did) => {
16381638
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
16391639
match tcx.const_eval(param_env.and((expr_did, substs))) {
1640-
Ok(ConstVal::Integral(v)) => {
1640+
Ok(&ConstVal::Integral(v)) => {
16411641
explicit_value = v;
16421642
break;
16431643
}

0 commit comments

Comments
 (0)