Skip to content

Commit 50076b0

Browse files
committed
rustc: intern ConstVal's in TyCtxt.
1 parent e6bce95 commit 50076b0

File tree

31 files changed

+347
-240
lines changed

31 files changed

+347
-240
lines changed

src/librustc/hir/mod.rs

+1-1
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

+19-19
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 middle::region;
2120
use ty;
2221

@@ -272,59 +271,60 @@ for ::middle::const_val::ConstVal<'gcx> {
272271
fn hash_stable<W: StableHasherResult>(&self,
273272
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
274273
hasher: &mut StableHasher<W>) {
275-
use middle::const_val::ConstVal;
274+
use middle::const_val::ConstVal::*;
275+
use middle::const_val::ConstAggregate::*;
276276

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

279279
match *self {
280-
ConstVal::Float(ref value) => {
280+
Float(ref value) => {
281281
value.hash_stable(hcx, hasher);
282282
}
283-
ConstVal::Integral(ref value) => {
283+
Integral(ref value) => {
284284
value.hash_stable(hcx, hasher);
285285
}
286-
ConstVal::Str(ref value) => {
286+
Str(ref value) => {
287287
value.hash_stable(hcx, hasher);
288288
}
289-
ConstVal::ByteStr(ref value) => {
289+
ByteStr(ref value) => {
290290
value.hash_stable(hcx, hasher);
291291
}
292-
ConstVal::Bool(value) => {
292+
Bool(value) => {
293293
value.hash_stable(hcx, hasher);
294294
}
295-
ConstVal::Char(value) => {
295+
Char(value) => {
296296
value.hash_stable(hcx, hasher);
297297
}
298-
ConstVal::Variant(def_id) => {
298+
Variant(def_id) => {
299299
def_id.hash_stable(hcx, hasher);
300300
}
301-
ConstVal::Function(def_id, substs) => {
301+
Function(def_id, substs) => {
302302
def_id.hash_stable(hcx, hasher);
303303
substs.hash_stable(hcx, hasher);
304304
}
305-
ConstVal::Struct(ref name_value_map) => {
306-
let mut values: Vec<(InternedString, &ConstVal)> =
307-
name_value_map.iter()
308-
.map(|(name, val)| (name.as_str(), val))
309-
.collect();
310-
305+
Aggregate(Struct(ref name_values)) => {
306+
let mut values = name_values.to_vec();
311307
values.sort_unstable_by_key(|&(ref name, _)| name.clone());
312308
values.hash_stable(hcx, hasher);
313309
}
314-
ConstVal::Tuple(ref value) => {
310+
Aggregate(Tuple(ref value)) => {
315311
value.hash_stable(hcx, hasher);
316312
}
317-
ConstVal::Array(ref value) => {
313+
Aggregate(Array(ref value)) => {
318314
value.hash_stable(hcx, hasher);
319315
}
320-
ConstVal::Repeat(ref value, times) => {
316+
Aggregate(Repeat(ref value, times)) => {
321317
value.hash_stable(hcx, hasher);
322318
times.hash_stable(hcx, hasher);
323319
}
324320
}
325321
}
326322
}
327323

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

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

src/librustc/middle/const_val.rs

+40-14
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

+8-7
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

@@ -1478,7 +1480,7 @@ pub enum Literal<'tcx> {
14781480
substs: &'tcx Substs<'tcx>,
14791481
},
14801482
Value {
1481-
value: ConstVal<'tcx>,
1483+
value: &'tcx ConstVal<'tcx>,
14821484
},
14831485
Promoted {
14841486
// Index into the `promoted` vector of `Mir`.
@@ -1516,9 +1518,9 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
15161518
match *const_val {
15171519
Float(f) => write!(fmt, "{:?}", f),
15181520
Integral(n) => write!(fmt, "{}", n),
1519-
Str(ref s) => write!(fmt, "{:?}", s),
1520-
ByteStr(ref bytes) => {
1521-
let escaped: String = bytes
1521+
Str(s) => write!(fmt, "{:?}", s),
1522+
ByteStr(bytes) => {
1523+
let escaped: String = bytes.data
15221524
.iter()
15231525
.flat_map(|&ch| ascii::escape_default(ch).map(|c| c as char))
15241526
.collect();
@@ -1528,8 +1530,7 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
15281530
Char(c) => write!(fmt, "{:?}", c),
15291531
Variant(def_id) |
15301532
Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
1531-
Struct(_) | Tuple(_) | Array(_) | Repeat(..) =>
1532-
bug!("ConstVal `{:?}` should not be in MIR", const_val),
1533+
Aggregate(_) => bug!("`ConstVal::{:?}` should not be in MIR", const_val),
15331534
}
15341535
}
15351536

src/librustc/mir/visit.rs

+2-2
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
}
@@ -760,7 +760,7 @@ macro_rules! make_mir_visitor {
760760
_substs: & $($mutability)* ClosureSubsts<'tcx>) {
761761
}
762762

763-
fn super_const_val(&mut self, _const_val: & $($mutability)* ConstVal) {
763+
fn super_const_val(&mut self, _const_val: & $($mutability)* &'tcx ConstVal<'tcx>) {
764764
}
765765

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

src/librustc/ty/context.rs

+37-1
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::{self, ObjectLifetimeDefault};
@@ -108,6 +109,7 @@ pub struct CtxtInterners<'tcx> {
108109
region: RefCell<FxHashSet<Interned<'tcx, RegionKind>>>,
109110
existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>,
110111
predicates: RefCell<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>,
112+
const_: RefCell<FxHashSet<Interned<'tcx, ConstVal<'tcx>>>>,
111113
}
112114

113115
impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
@@ -120,6 +122,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
120122
region: RefCell::new(FxHashSet()),
121123
existential_predicates: RefCell::new(FxHashSet()),
122124
predicates: RefCell::new(FxHashSet()),
125+
const_: RefCell::new(FxHashSet()),
123126
}
124127
}
125128

@@ -934,6 +937,32 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
934937
self.global_arenas.adt_def.alloc(def)
935938
}
936939

940+
pub fn alloc_byte_array(self, bytes: &[u8]) -> &'gcx [u8] {
941+
if bytes.is_empty() {
942+
&[]
943+
} else {
944+
self.global_interners.arena.alloc_slice(bytes)
945+
}
946+
}
947+
948+
pub fn alloc_constval_slice(self, values: &[&'tcx ConstVal<'gcx>])
949+
-> &'gcx [&'tcx ConstVal<'gcx>] {
950+
if values.is_empty() {
951+
&[]
952+
} else {
953+
self.global_interners.arena.alloc_slice(values)
954+
}
955+
}
956+
957+
pub fn alloc_name_constval_slice(self, values: &[(ast::Name, &'tcx ConstVal<'gcx>)])
958+
-> &'gcx [(ast::Name, &'tcx ConstVal<'gcx>)] {
959+
if values.is_empty() {
960+
&[]
961+
} else {
962+
self.global_interners.arena.alloc_slice(values)
963+
}
964+
}
965+
937966
pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
938967
if let Some(st) = self.stability_interner.borrow().get(&stab) {
939968
return st;
@@ -1507,6 +1536,12 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Predicate<'lcx>]>
15071536
}
15081537
}
15091538

1539+
impl<'tcx: 'lcx, 'lcx> Borrow<ConstVal<'lcx>> for Interned<'tcx, ConstVal<'tcx>> {
1540+
fn borrow<'a>(&'a self) -> &'a ConstVal<'lcx> {
1541+
&self.0
1542+
}
1543+
}
1544+
15101545
macro_rules! intern_method {
15111546
($lt_tcx:tt, $name:ident: $method:ident($alloc:ty,
15121547
$alloc_method:ident,
@@ -1587,7 +1622,8 @@ direct_interners!('tcx,
15871622
&ty::ReVar(_) | &ty::ReSkolemized(..) => true,
15881623
_ => false
15891624
}
1590-
}) -> RegionKind
1625+
}) -> RegionKind,
1626+
const_: mk_const(/*|c: &Const| keep_local(&c.ty)*/ |_| false) -> ConstVal<'tcx>
15911627
);
15921628

15931629
macro_rules! slice_interners {

src/librustc/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
16011601
if let VariantDiscr::Explicit(expr_did) = v.discr {
16021602
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
16031603
match tcx.const_eval(param_env.and((expr_did, substs))) {
1604-
Ok(ConstVal::Integral(v)) => {
1604+
Ok(&ConstVal::Integral(v)) => {
16051605
discr = v;
16061606
}
16071607
err => {
@@ -1641,7 +1641,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
16411641
ty::VariantDiscr::Explicit(expr_did) => {
16421642
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
16431643
match tcx.const_eval(param_env.and((expr_did, substs))) {
1644-
Ok(ConstVal::Integral(v)) => {
1644+
Ok(&ConstVal::Integral(v)) => {
16451645
explicit_value = v;
16461646
break;
16471647
}

0 commit comments

Comments
 (0)