Utilize AccumulateVec to avoid heap allocations in mk_{substs, type_list, tup} calls.

This commit is contained in:
Mark-Simulacrum 2016-10-24 18:23:29 -06:00
parent a4f7ba376e
commit 982a48575b
35 changed files with 193 additions and 144 deletions

View File

@ -157,13 +157,15 @@ impl<T> TypedArena<T> {
/// Allocates a slice of objects that are copy into the `TypedArena`, returning a mutable /// Allocates a slice of objects that are copy into the `TypedArena`, returning a mutable
/// reference to it. Will panic if passed a zero-sized types. /// reference to it. Will panic if passed a zero-sized types.
///
/// Panics:
/// - Zero-sized types
/// - Zero-length slices
#[inline] #[inline]
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
where T: Copy { where T: Copy {
assert!(mem::size_of::<T>() != 0); assert!(mem::size_of::<T>() != 0);
if slice.len() == 0 { assert!(slice.len() != 0);
return unsafe { slice::from_raw_parts_mut(heap::EMPTY as *mut T, 0) };
}
let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize; let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize;
let at_least_bytes = slice.len() * mem::size_of::<T>(); let at_least_bytes = slice.len() * mem::size_of::<T>();

View File

@ -163,7 +163,7 @@ impl<'tcx> Rvalue<'tcx> {
let lhs_ty = lhs.ty(mir, tcx); let lhs_ty = lhs.ty(mir, tcx);
let rhs_ty = rhs.ty(mir, tcx); let rhs_ty = rhs.ty(mir, tcx);
let ty = op.ty(tcx, lhs_ty, rhs_ty); let ty = op.ty(tcx, lhs_ty, rhs_ty);
let ty = tcx.mk_tup(&[ty, tcx.types.bool]); let ty = tcx.intern_tup(&[ty, tcx.types.bool]);
Some(ty) Some(ty)
} }
&Rvalue::UnaryOp(_, ref operand) => { &Rvalue::UnaryOp(_, ref operand) => {
@ -184,7 +184,7 @@ impl<'tcx> Rvalue<'tcx> {
} }
AggregateKind::Tuple => { AggregateKind::Tuple => {
Some(tcx.mk_tup( Some(tcx.mk_tup(
&ops.iter().map(|op| op.ty(mir, tcx)).collect::<Vec<_>>() ops.iter().map(|op| op.ty(mir, tcx))
)) ))
} }
AggregateKind::Adt(def, _, substs, _) => { AggregateKind::Adt(def, _, substs, _) => {

View File

@ -11,7 +11,7 @@
use dep_graph::DepGraph; use dep_graph::DepGraph;
use infer::{InferCtxt, InferOk}; use infer::{InferCtxt, InferOk};
use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, TyCtxt, ToPredicate}; use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, TyCtxt, ToPredicate};
use ty::subst::{Substs, Subst}; use ty::subst::Subst;
use rustc_data_structures::obligation_forest::{ObligationForest, Error}; use rustc_data_structures::obligation_forest::{ObligationForest, Error};
use rustc_data_structures::obligation_forest::{ForestObligation, ObligationProcessor}; use rustc_data_structures::obligation_forest::{ForestObligation, ObligationProcessor};
use std::marker::PhantomData; use std::marker::PhantomData;
@ -159,7 +159,7 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> {
let concrete_ty = ty_scheme.ty.subst(tcx, substs); let concrete_ty = ty_scheme.ty.subst(tcx, substs);
let predicate = ty::TraitRef { let predicate = ty::TraitRef {
def_id: self.predicate.def_id(), def_id: self.predicate.def_id(),
substs: Substs::new_trait(tcx, concrete_ty, &[]) substs: tcx.mk_substs_trait(concrete_ty, &[])
}.to_predicate(); }.to_predicate();
let original_obligation = Obligation::new(self.cause.clone(), let original_obligation = Obligation::new(self.cause.clone(),

View File

@ -2599,7 +2599,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
k k
} }
}); });
let substs = Substs::new(tcx, params); let substs = tcx.mk_substs(params);
for &ty in fields.split_last().unwrap().1 { for &ty in fields.split_last().unwrap().1 {
if ty.subst(tcx, substs).references_error() { if ty.subst(tcx, substs).references_error() {
return Err(Unimplemented); return Err(Unimplemented);
@ -2619,7 +2619,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
k k
} }
}); });
let new_struct = tcx.mk_adt(def, Substs::new(tcx, params)); let new_struct = tcx.mk_adt(def, tcx.mk_substs(params));
let origin = TypeOrigin::Misc(obligation.cause.span); let origin = TypeOrigin::Misc(obligation.cause.span);
let InferOk { obligations, .. } = let InferOk { obligations, .. } =
self.infcx.sub_types(false, origin, new_struct, target) self.infcx.sub_types(false, origin, new_struct, target)

View File

@ -380,7 +380,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
Ok(def_id) => { Ok(def_id) => {
Ok(ty::TraitRef { Ok(ty::TraitRef {
def_id: def_id, def_id: def_id,
substs: Substs::new_trait(self, param_ty, &[]) substs: self.mk_substs_trait(param_ty, &[])
}) })
} }
Err(e) => { Err(e) => {
@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{ {
let trait_ref = ty::TraitRef { let trait_ref = ty::TraitRef {
def_id: trait_def_id, def_id: trait_def_id,
substs: Substs::new_trait(self, param_ty, ty_params) substs: self.mk_substs_trait(param_ty, ty_params)
}; };
predicate_for_trait_ref(cause, trait_ref, recursion_depth) predicate_for_trait_ref(cause, trait_ref, recursion_depth)
} }
@ -486,11 +486,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{ {
let arguments_tuple = match tuple_arguments { let arguments_tuple = match tuple_arguments {
TupleArgumentsFlag::No => sig.0.inputs[0], TupleArgumentsFlag::No => sig.0.inputs[0],
TupleArgumentsFlag::Yes => self.mk_tup(&sig.0.inputs), TupleArgumentsFlag::Yes => self.intern_tup(&sig.0.inputs[..]),
}; };
let trait_ref = ty::TraitRef { let trait_ref = ty::TraitRef {
def_id: fn_trait_def_id, def_id: fn_trait_def_id,
substs: Substs::new_trait(self, self_ty, &[arguments_tuple]), substs: self.mk_substs_trait(self_ty, &[arguments_tuple]),
}; };
ty::Binder((trait_ref, sig.0.output)) ty::Binder((trait_ref, sig.0.output))
} }

View File

@ -36,6 +36,7 @@ use ty::maps;
use util::common::MemoizationMap; use util::common::MemoizationMap;
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
use util::nodemap::{FnvHashMap, FnvHashSet}; use util::nodemap::{FnvHashMap, FnvHashSet};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use arena::TypedArena; use arena::TypedArena;
use std::borrow::Borrow; use std::borrow::Borrow;
@ -44,6 +45,7 @@ use std::hash::{Hash, Hasher};
use std::mem; use std::mem;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::iter;
use syntax::ast::{self, Name, NodeId}; use syntax::ast::{self, Name, NodeId};
use syntax::attr; use syntax::attr;
use syntax::parse::token::{self, keywords}; use syntax::parse::token::{self, keywords};
@ -824,6 +826,9 @@ impl<'a, 'tcx> Lift<'tcx> for Ty<'a> {
impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> { impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
type Lifted = &'tcx Substs<'tcx>; type Lifted = &'tcx Substs<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> { fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Substs<'tcx>> {
if self.len() == 0 {
return Some(Slice::empty());
}
if let Some(&Interned(substs)) = tcx.interners.substs.borrow().get(&self[..]) { if let Some(&Interned(substs)) = tcx.interners.substs.borrow().get(&self[..]) {
if *self as *const _ == substs as *const _ { if *self as *const _ == substs as *const _ {
return Some(substs); return Some(substs);
@ -859,6 +864,9 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Ty<'a>> {
type Lifted = &'tcx Slice<Ty<'tcx>>; type Lifted = &'tcx Slice<Ty<'tcx>>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
-> Option<&'tcx Slice<Ty<'tcx>>> { -> Option<&'tcx Slice<Ty<'tcx>>> {
if self.len() == 0 {
return Some(Slice::empty());
}
if let Some(&Interned(list)) = tcx.interners.type_list.borrow().get(&self[..]) { if let Some(&Interned(list)) = tcx.interners.type_list.borrow().get(&self[..]) {
if *self as *const _ == list as *const _ { if *self as *const _ == list as *const _ {
return Some(list); return Some(list);
@ -1212,8 +1220,8 @@ macro_rules! slice_interners {
} }
slice_interners!( slice_interners!(
type_list: mk_type_list(Ty), type_list: _intern_type_list(Ty),
substs: mk_substs(Kind) substs: _intern_substs(Kind)
); );
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
@ -1318,12 +1326,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.mk_ty(TySlice(ty)) self.mk_ty(TySlice(ty))
} }
pub fn mk_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> { pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
self.mk_ty(TyTuple(self.mk_type_list(ts))) self.mk_ty(TyTuple(self.intern_type_list(ts)))
}
pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts))))
} }
pub fn mk_nil(self) -> Ty<'tcx> { pub fn mk_nil(self) -> Ty<'tcx> {
self.mk_tup(&[]) self.intern_tup(&[])
} }
pub fn mk_diverging_default(self) -> Ty<'tcx> { pub fn mk_diverging_default(self) -> Ty<'tcx> {
@ -1369,7 +1381,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-> Ty<'tcx> { -> Ty<'tcx> {
self.mk_closure_from_closure_substs(closure_id, ClosureSubsts { self.mk_closure_from_closure_substs(closure_id, ClosureSubsts {
func_substs: substs, func_substs: substs,
upvar_tys: self.mk_type_list(tys) upvar_tys: self.intern_type_list(tys)
}) })
} }
@ -1414,6 +1426,40 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.mk_ty(TyAnon(def_id, substs)) self.mk_ty(TyAnon(def_id, substs))
} }
pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx Slice<Ty<'tcx>> {
if ts.len() == 0 {
Slice::empty()
} else {
self._intern_type_list(ts)
}
}
pub fn intern_substs(self, ts: &[Kind<'tcx>]) -> &'tcx Slice<Kind<'tcx>> {
if ts.len() == 0 {
Slice::empty()
} else {
self._intern_substs(ts)
}
}
pub fn mk_type_list<I: InternAs<[Ty<'tcx>],
&'tcx Slice<Ty<'tcx>>>>(self, iter: I) -> I::Output {
iter.intern_with(|xs| self.intern_type_list(xs))
}
pub fn mk_substs<I: InternAs<[Kind<'tcx>],
&'tcx Slice<Kind<'tcx>>>>(self, iter: I) -> I::Output {
iter.intern_with(|xs| self.intern_substs(xs))
}
pub fn mk_substs_trait(self,
s: Ty<'tcx>,
t: &[Ty<'tcx>])
-> &'tcx Substs<'tcx>
{
self.mk_substs(iter::once(s).chain(t.into_iter().cloned()).map(Kind::from))
}
pub fn trait_items(self, trait_did: DefId) -> Rc<Vec<ty::ImplOrTraitItem<'gcx>>> { pub fn trait_items(self, trait_did: DefId) -> Rc<Vec<ty::ImplOrTraitItem<'gcx>>> {
self.trait_items_cache.memoize(trait_did, || { self.trait_items_cache.memoize(trait_did, || {
let def_ids = self.impl_or_trait_items(trait_did); let def_ids = self.impl_or_trait_items(trait_did);
@ -1432,3 +1478,39 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}) })
} }
} }
pub trait InternAs<T: ?Sized, R> {
type Output;
fn intern_with<F>(self, F) -> Self::Output
where F: FnOnce(&T) -> R;
}
impl<I, T, R, E> InternAs<[T], R> for I
where E: InternIteratorElement<T, R>,
I: Iterator<Item=E> {
type Output = E::Output;
fn intern_with<F>(self, f: F) -> Self::Output
where F: FnOnce(&[T]) -> R {
E::intern_with(self, f)
}
}
pub trait InternIteratorElement<T, R>: Sized {
type Output;
fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output;
}
impl<T, R> InternIteratorElement<T, R> for T {
type Output = R;
fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
f(&iter.collect::<AccumulateVec<[_; 8]>>())
}
}
impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
type Output = Result<R, E>;
fn intern_with<I: Iterator<Item=Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
Ok(f(&iter.collect::<Result<AccumulateVec<[_; 8]>, _>>()?))
}
}

View File

@ -41,6 +41,7 @@ use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::slice; use std::slice;
use std::vec::IntoIter; use std::vec::IntoIter;
use std::mem;
use syntax::ast::{self, Name, NodeId}; use syntax::ast::{self, Name, NodeId};
use syntax::attr; use syntax::attr;
use syntax::parse::token::{self, InternedString}; use syntax::parse::token::{self, InternedString};
@ -560,6 +561,14 @@ impl<'a, T> IntoIterator for &'a Slice<T> {
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {} impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Slice<Ty<'tcx>> {}
impl<T> Slice<T> {
pub fn empty<'a>() -> &'a Slice<T> {
unsafe {
mem::transmute(slice::from_raw_parts(0x1 as *const T, 0))
}
}
}
/// Upvars do not get their own node-id. Instead, we use the pair of /// Upvars do not get their own node-id. Instead, we use the pair of
/// the original var id (that is, the root variable that is referenced /// the original var id (that is, the root variable that is referenced
/// by the upvar) and the id of the closure expression. /// by the upvar) and the id of the closure expression.
@ -1797,7 +1806,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
_ if tys.references_error() => tcx.types.err, _ if tys.references_error() => tcx.types.err,
0 => tcx.types.bool, 0 => tcx.types.bool,
1 => tys[0], 1 => tys[0],
_ => tcx.mk_tup(&tys) _ => tcx.intern_tup(&tys[..])
}; };
match self.sized_constraint.get(dep_node()) { match self.sized_constraint.get(dep_node()) {
@ -1873,7 +1882,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
}; };
let sized_predicate = Binder(TraitRef { let sized_predicate = Binder(TraitRef {
def_id: sized_trait, def_id: sized_trait,
substs: Substs::new_trait(tcx, ty, &[]) substs: tcx.mk_substs_trait(ty, &[])
}).to_predicate(); }).to_predicate();
let predicates = tcx.lookup_predicates(self.did).predicates; let predicates = tcx.lookup_predicates(self.did).predicates;
if predicates.into_iter().any(|p| p == sized_predicate) { if predicates.into_iter().any(|p| p == sized_predicate) {
@ -2124,7 +2133,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn node_id_item_substs(self, id: NodeId) -> ItemSubsts<'gcx> { pub fn node_id_item_substs(self, id: NodeId) -> ItemSubsts<'gcx> {
match self.tables.borrow().item_substs.get(&id) { match self.tables.borrow().item_substs.get(&id) {
None => ItemSubsts { None => ItemSubsts {
substs: Substs::empty(self.global_tcx()) substs: self.global_tcx().intern_substs(&[])
}, },
Some(ts) => ts.clone(), Some(ts) => ts.clone(),
} }
@ -2796,7 +2805,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// regions, so it shouldn't matter what we use for the free id // regions, so it shouldn't matter what we use for the free id
let free_id_outlive = self.region_maps.node_extent(ast::DUMMY_NODE_ID); let free_id_outlive = self.region_maps.node_extent(ast::DUMMY_NODE_ID);
ty::ParameterEnvironment { ty::ParameterEnvironment {
free_substs: Substs::empty(self), free_substs: self.intern_substs(&[]),
caller_bounds: Vec::new(), caller_bounds: Vec::new(),
implicit_region_bound: self.mk_region(ty::ReEmpty), implicit_region_bound: self.mk_region(ty::ReEmpty),
free_id_outlive: free_id_outlive, free_id_outlive: free_id_outlive,

View File

@ -49,12 +49,6 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
Relate::relate(self, a, b) Relate::relate(self, a, b)
} }
/// Relete elements of two slices pairwise.
fn relate_zip<T: Relate<'tcx>>(&mut self, a: &[T], b: &[T]) -> RelateResult<'tcx, Vec<T>> {
assert_eq!(a.len(), b.len());
a.iter().zip(b).map(|(a, b)| self.relate(a, b)).collect()
}
/// Switch variance for the purpose of relating `a` and `b`. /// Switch variance for the purpose of relating `a` and `b`.
fn relate_with_variance<T: Relate<'tcx>>(&mut self, fn relate_with_variance<T: Relate<'tcx>>(&mut self,
variance: ty::Variance, variance: ty::Variance,
@ -158,7 +152,7 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
} }
}); });
Substs::maybe_new(tcx, params) Ok(tcx.mk_substs(params)?)
} }
impl<'tcx> Relate<'tcx> for &'tcx ty::BareFnTy<'tcx> { impl<'tcx> Relate<'tcx> for &'tcx ty::BareFnTy<'tcx> {
@ -489,10 +483,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
(&ty::TyTuple(as_), &ty::TyTuple(bs)) => (&ty::TyTuple(as_), &ty::TyTuple(bs)) =>
{ {
if as_.len() == bs.len() { if as_.len() == bs.len() {
let ts = as_.iter().zip(bs) Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?)
.map(|(a, b)| relation.relate(a, b))
.collect::<Result<Vec<_>, _>>()?;
Ok(tcx.mk_tup(&ts))
} else if !(as_.is_empty() || bs.is_empty()) { } else if !(as_.is_empty() || bs.is_empty()) {
Err(TypeError::TupleSize( Err(TypeError::TupleSize(
expected_found(relation, &as_.len(), &bs.len()))) expected_found(relation, &as_.len(), &bs.len())))
@ -544,10 +535,11 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{ {
let substs = relate_substs(relation, None, a.func_substs, b.func_substs)?; let substs = relate_substs(relation, None, a.func_substs, b.func_substs)?;
let upvar_tys = relation.relate_zip(&a.upvar_tys, &b.upvar_tys)?; assert_eq!(a.upvar_tys.len(), b.upvar_tys.len());
Ok(ty::ClosureSubsts { Ok(ty::ClosureSubsts {
func_substs: substs, func_substs: substs,
upvar_tys: relation.tcx().mk_type_list(&upvar_tys) upvar_tys: relation.tcx().mk_type_list(
a.upvar_tys.iter().zip(b.upvar_tys).map(|(a, b)| relation.relate(a, b)))?
}) })
} }
} }

View File

@ -11,6 +11,7 @@
use infer::type_variable; use infer::type_variable;
use ty::{self, Lift, Ty, TyCtxt}; use ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use std::rc::Rc; use std::rc::Rc;
use syntax::abi; use syntax::abi;
@ -448,8 +449,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<Ty<'tcx>> { impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<Ty<'tcx>> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let tys = self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>(); let v = self.iter().map(|t| t.fold_with(folder)).collect::<AccumulateVec<[_; 8]>>();
folder.tcx().mk_type_list(&tys) folder.tcx().intern_type_list(&v)
} }
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {

View File

@ -16,6 +16,7 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use serialize::{self, Encodable, Encoder, Decodable, Decoder}; use serialize::{self, Encodable, Encoder, Decodable, Decoder};
use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::{Span, DUMMY_SP};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use core::nonzero::NonZero; use core::nonzero::NonZero;
use std::fmt; use std::fmt;
@ -164,31 +165,6 @@ impl<'tcx> Decodable for Kind<'tcx> {
pub type Substs<'tcx> = Slice<Kind<'tcx>>; pub type Substs<'tcx> = Slice<Kind<'tcx>>;
impl<'a, 'gcx, 'tcx> Substs<'tcx> { impl<'a, 'gcx, 'tcx> Substs<'tcx> {
pub fn new<I>(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I)
-> &'tcx Substs<'tcx>
where I: IntoIterator<Item=Kind<'tcx>> {
tcx.mk_substs(&params.into_iter().collect::<Vec<_>>())
}
pub fn maybe_new<I, E>(tcx: TyCtxt<'a, 'gcx, 'tcx>, params: I)
-> Result<&'tcx Substs<'tcx>, E>
where I: IntoIterator<Item=Result<Kind<'tcx>, E>> {
Ok(Substs::new(tcx, params.into_iter().collect::<Result<Vec<_>, _>>()?))
}
pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>,
s: Ty<'tcx>,
t: &[Ty<'tcx>])
-> &'tcx Substs<'tcx>
{
let t = iter::once(s).chain(t.iter().cloned());
Substs::new(tcx, t.map(Kind::from))
}
pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> {
Substs::new(tcx, iter::empty())
}
/// Creates a Substs for generic parameter definitions, /// Creates a Substs for generic parameter definitions,
/// by calling closures to obtain each region and type. /// by calling closures to obtain each region and type.
/// The closures get to observe the Substs as they're /// The closures get to observe the Substs as they're
@ -203,10 +179,8 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> { FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> {
let defs = tcx.lookup_generics(def_id); let defs = tcx.lookup_generics(def_id);
let mut substs = Vec::with_capacity(defs.count()); let mut substs = Vec::with_capacity(defs.count());
Substs::fill_item(&mut substs, tcx, defs, &mut mk_region, &mut mk_type); Substs::fill_item(&mut substs, tcx, defs, &mut mk_region, &mut mk_type);
tcx.intern_substs(&substs)
Substs::new(tcx, substs)
} }
fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>, fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
@ -298,20 +272,20 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
target_substs: &Substs<'tcx>) target_substs: &Substs<'tcx>)
-> &'tcx Substs<'tcx> { -> &'tcx Substs<'tcx> {
let defs = tcx.lookup_generics(source_ancestor); let defs = tcx.lookup_generics(source_ancestor);
Substs::new(tcx, target_substs.iter().chain(&self[defs.own_count()..]).cloned()) tcx.mk_substs(target_substs.iter().chain(&self[defs.own_count()..]).cloned())
} }
} }
impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> { impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let params: Vec<_> = self.iter().map(|k| k.fold_with(folder)).collect(); let params: AccumulateVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
// If folding doesn't change the substs, it's faster to avoid // If folding doesn't change the substs, it's faster to avoid
// calling `mk_substs` and instead reuse the existing substs. // calling `mk_substs` and instead reuse the existing substs.
if params[..] == self[..] { if params[..] == self[..] {
self self
} else { } else {
folder.tcx().mk_substs(&params) folder.tcx().intern_substs(&params)
} }
} }
@ -547,10 +521,9 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
-> ty::TraitRef<'tcx> { -> ty::TraitRef<'tcx> {
let defs = tcx.lookup_generics(trait_id); let defs = tcx.lookup_generics(trait_id);
let params = substs[..defs.own_count()].iter().cloned();
ty::TraitRef { ty::TraitRef {
def_id: trait_id, def_id: trait_id,
substs: Substs::new(tcx, params) substs: tcx.intern_substs(&substs[..defs.own_count()])
} }
} }
} }
@ -562,10 +535,9 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
// Assert there is a Self. // Assert there is a Self.
trait_ref.substs.type_at(0); trait_ref.substs.type_at(0);
let params = trait_ref.substs[1..].iter().cloned();
ty::ExistentialTraitRef { ty::ExistentialTraitRef {
def_id: trait_ref.def_id, def_id: trait_ref.def_id,
substs: Substs::new(tcx, params) substs: tcx.intern_substs(&trait_ref.substs[1..])
} }
} }
} }
@ -582,11 +554,10 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
assert!(!self_ty.has_escaping_regions()); assert!(!self_ty.has_escaping_regions());
self.map_bound(|trait_ref| { self.map_bound(|trait_ref| {
let params = trait_ref.substs.iter().cloned();
let params = iter::once(Kind::from(self_ty)).chain(params);
ty::TraitRef { ty::TraitRef {
def_id: trait_ref.def_id, def_id: trait_ref.def_id,
substs: Substs::new(tcx, params) substs: tcx.mk_substs(
iter::once(Kind::from(self_ty)).chain(trait_ref.substs.iter().cloned()))
} }
}) })
} }

View File

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use hir::def_id::DefId; use hir::def_id::DefId;
use ty::subst::{self, Subst, Substs}; use ty::subst::{self, Subst};
use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
use ty::{TyBool, TyChar, TyAdt}; use ty::{TyBool, TyChar, TyAdt};
use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
@ -886,7 +886,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
// by looking up the projections associated with the def_id. // by looking up the projections associated with the def_id.
let item_predicates = tcx.lookup_predicates(def_id); let item_predicates = tcx.lookup_predicates(def_id);
let substs = tcx.lift(&substs).unwrap_or_else(|| { let substs = tcx.lift(&substs).unwrap_or_else(|| {
Substs::empty(tcx) tcx.intern_substs(&[])
}); });
let bounds = item_predicates.instantiate(tcx, substs); let bounds = item_predicates.instantiate(tcx, substs);

View File

@ -857,7 +857,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let unit_temp = Lvalue::Local(self.patch.new_temp(tcx.mk_nil())); let unit_temp = Lvalue::Local(self.patch.new_temp(tcx.mk_nil()));
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem) let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
.unwrap_or_else(|e| tcx.sess.fatal(&e)); .unwrap_or_else(|e| tcx.sess.fatal(&e));
let substs = Substs::new(tcx, iter::once(Kind::from(ty))); let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs); let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
self.patch.new_block(BasicBlockData { self.patch.new_block(BasicBlockData {

View File

@ -20,14 +20,13 @@ use rustc::middle::region::{self, CodeExtent};
use rustc::middle::region::CodeExtentData; use rustc::middle::region::CodeExtentData;
use rustc::middle::resolve_lifetime; use rustc::middle::resolve_lifetime;
use rustc::middle::stability; use rustc::middle::stability;
use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::ty::subst::{Kind, Subst};
use rustc::traits::Reveal; use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::infer::{self, InferOk, InferResult, TypeOrigin}; use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
use rustc_metadata::cstore::CStore; use rustc_metadata::cstore::CStore;
use rustc::hir::map as hir_map; use rustc::hir::map as hir_map;
use rustc::session::{self, config}; use rustc::session::{self, config};
use std::iter;
use std::rc::Rc; use std::rc::Rc;
use syntax::ast; use syntax::ast;
use syntax::abi::Abi; use syntax::abi::Abi;
@ -275,7 +274,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
} }
pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> { pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
self.infcx.tcx.mk_tup(&[ty1, ty2]) self.infcx.tcx.intern_tup(&[ty1, ty2])
} }
pub fn t_param(&self, index: u32) -> Ty<'tcx> { pub fn t_param(&self, index: u32) -> Ty<'tcx> {
@ -679,7 +678,7 @@ fn subst_ty_renumber_bound() {
env.t_fn(&[t_param], env.t_nil()) env.t_fn(&[t_param], env.t_nil())
}; };
let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(t_rptr_bound1))); let substs = env.infcx.tcx.intern_substs(&[Kind::from(t_rptr_bound1)]);
let t_substituted = t_source.subst(env.infcx.tcx, substs); let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = fn(&'a isize) // t_expected = fn(&'a isize)
@ -714,7 +713,7 @@ fn subst_ty_renumber_some_bounds() {
env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil())) env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil()))
}; };
let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(t_rptr_bound1))); let substs = env.infcx.tcx.intern_substs(&[Kind::from(t_rptr_bound1)]);
let t_substituted = t_source.subst(env.infcx.tcx, substs); let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = (&'a isize, fn(&'a isize)) // t_expected = (&'a isize, fn(&'a isize))
@ -776,7 +775,7 @@ fn subst_region_renumber_region() {
env.t_fn(&[env.t_rptr(re_early)], env.t_nil()) env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
}; };
let substs = Substs::new(env.infcx.tcx, iter::once(Kind::from(re_bound1))); let substs = env.infcx.tcx.intern_substs(&[Kind::from(re_bound1)]);
let t_substituted = t_source.subst(env.infcx.tcx, substs); let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = fn(&'a isize) // t_expected = fn(&'a isize)
@ -803,8 +802,8 @@ fn walk_ty() {
let tcx = env.infcx.tcx; let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize; let int_ty = tcx.types.isize;
let uint_ty = tcx.types.usize; let uint_ty = tcx.types.usize;
let tup1_ty = tcx.mk_tup(&[int_ty, uint_ty, int_ty, uint_ty]); let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.mk_tup(&[tup1_ty, tup1_ty, uint_ty]); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]);
let uniq_ty = tcx.mk_box(tup2_ty); let uniq_ty = tcx.mk_box(tup2_ty);
let walked: Vec<_> = uniq_ty.walk().collect(); let walked: Vec<_> = uniq_ty.walk().collect();
assert_eq!(walked, assert_eq!(walked,
@ -819,8 +818,8 @@ fn walk_ty_skip_subtree() {
let tcx = env.infcx.tcx; let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize; let int_ty = tcx.types.isize;
let uint_ty = tcx.types.usize; let uint_ty = tcx.types.usize;
let tup1_ty = tcx.mk_tup(&[int_ty, uint_ty, int_ty, uint_ty]); let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.mk_tup(&[tup1_ty, tup1_ty, uint_ty]); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]);
let uniq_ty = tcx.mk_box(tup2_ty); let uniq_ty = tcx.mk_box(tup2_ty);
// types we expect to see (in order), plus a boolean saying // types we expect to see (in order), plus a boolean saying

View File

@ -503,21 +503,21 @@ impl LateLintPass for MissingCopyImplementations {
return; return;
} }
let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id)); let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id));
(def, cx.tcx.mk_adt(def, Substs::empty(cx.tcx))) (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
} }
hir::ItemUnion(_, ref ast_generics) => { hir::ItemUnion(_, ref ast_generics) => {
if ast_generics.is_parameterized() { if ast_generics.is_parameterized() {
return; return;
} }
let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id)); let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id));
(def, cx.tcx.mk_adt(def, Substs::empty(cx.tcx))) (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
} }
hir::ItemEnum(_, ref ast_generics) => { hir::ItemEnum(_, ref ast_generics) => {
if ast_generics.is_parameterized() { if ast_generics.is_parameterized() {
return; return;
} }
let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id)); let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id));
(def, cx.tcx.mk_adt(def, Substs::empty(cx.tcx))) (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[])))
} }
_ => return, _ => return,
}; };

View File

@ -374,7 +374,7 @@ impl<'a, 'tcx> SpecializedDecoder<ty::GenericPredicates<'tcx>> for DecodeContext
impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx> { impl<'a, 'tcx> SpecializedDecoder<&'tcx Substs<'tcx>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<&'tcx Substs<'tcx>, Self::Error> { fn specialized_decode(&mut self) -> Result<&'tcx Substs<'tcx>, Self::Error> {
Ok(self.tcx().mk_substs(&Vec::decode(self)?)) Ok(self.tcx().mk_substs((0..self.read_usize()?).map(|_| Decodable::decode(self)))?)
} }
} }
@ -386,7 +386,7 @@ impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Region> for DecodeContext<'a, 'tcx>
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> { impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::Slice<Ty<'tcx>>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> { fn specialized_decode(&mut self) -> Result<&'tcx ty::Slice<Ty<'tcx>>, Self::Error> {
Ok(self.tcx().mk_type_list(&Vec::decode(self)?)) Ok(self.tcx().mk_type_list((0..self.read_usize()?).map(|_| Decodable::decode(self)))?)
} }
} }

View File

@ -257,7 +257,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = self.source_info(span); let source_info = self.source_info(span);
let bool_ty = self.hir.bool_ty(); let bool_ty = self.hir.bool_ty();
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() { if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
let result_tup = self.hir.tcx().mk_tup(&[ty, bool_ty]); let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]);
let result_value = self.temp(result_tup); let result_value = self.temp(result_tup);
self.cfg.push_assign(block, source_info, self.cfg.push_assign(block, source_info,

View File

@ -89,15 +89,13 @@ should go to.
use build::{BlockAnd, BlockAndExtension, Builder, CFG, ScopeAuxiliary, ScopeId}; use build::{BlockAnd, BlockAndExtension, Builder, CFG, ScopeAuxiliary, ScopeId};
use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::middle::region::{CodeExtent, CodeExtentData};
use rustc::middle::lang_items; use rustc::middle::lang_items;
use rustc::ty::subst::{Kind, Substs, Subst}; use rustc::ty::subst::{Kind, Subst};
use rustc::ty::{Ty, TyCtxt}; use rustc::ty::{Ty, TyCtxt};
use rustc::mir::repr::*; use rustc::mir::repr::*;
use syntax_pos::Span; use syntax_pos::Span;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::fnv::FnvHashMap; use rustc_data_structures::fnv::FnvHashMap;
use std::iter;
pub struct Scope<'tcx> { pub struct Scope<'tcx> {
/// the scope-id within the scope_auxiliary /// the scope-id within the scope_auxiliary
id: ScopeId, id: ScopeId,
@ -800,7 +798,7 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-> TerminatorKind<'tcx> { -> TerminatorKind<'tcx> {
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem) let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
.unwrap_or_else(|e| tcx.sess.fatal(&e)); .unwrap_or_else(|e| tcx.sess.fatal(&e));
let substs = Substs::new(tcx, iter::once(Kind::from(data.item_ty))); let substs = tcx.intern_substs(&[Kind::from(data.item_ty)]);
TerminatorKind::Call { TerminatorKind::Call {
func: Operand::Constant(Constant { func: Operand::Constant(Constant {
span: data.span, span: data.span,

View File

@ -27,7 +27,7 @@ use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::FnKind; use rustc::hir::intravisit::FnKind;
use rustc::hir::map::blocks::FnLikeNode; use rustc::hir::map::blocks::FnLikeNode;
use rustc::infer::InferCtxt; use rustc::infer::InferCtxt;
use rustc::ty::subst::{Subst, Substs}; use rustc::ty::subst::Subst;
use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::{self, Ty, TyCtxt};
use syntax::parse::token; use syntax::parse::token;
use rustc::hir; use rustc::hir;
@ -146,7 +146,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
params: &[Ty<'tcx>]) params: &[Ty<'tcx>])
-> (Ty<'tcx>, Literal<'tcx>) { -> (Ty<'tcx>, Literal<'tcx>) {
let method_name = token::intern(method_name); let method_name = token::intern(method_name);
let substs = Substs::new_trait(self.tcx, self_ty, params); let substs = self.tcx.mk_substs_trait(self_ty, params);
for trait_item in self.tcx.trait_items(trait_def_id).iter() { for trait_item in self.tcx.trait_items(trait_def_id).iter() {
match *trait_item { match *trait_item {
ty::ImplOrTraitItem::MethodTraitItem(ref method) => { ty::ImplOrTraitItem::MethodTraitItem(ref method) => {

View File

@ -214,7 +214,7 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Allocate space: // Allocate space:
let def_id = require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem); let def_id = require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem);
let r = Callee::def(bcx.ccx(), def_id, Substs::empty(bcx.tcx())) let r = Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[]))
.call(bcx, debug_loc, &[size, align], None); .call(bcx, debug_loc, &[size, align], None);
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr)) Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
@ -405,7 +405,7 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx
-> CustomCoerceUnsized { -> CustomCoerceUnsized {
let trait_ref = ty::Binder(ty::TraitRef { let trait_ref = ty::Binder(ty::TraitRef {
def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(), def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(),
substs: Substs::new_trait(scx.tcx(), source_ty, &[target_ty]) substs: scx.tcx().mk_substs_trait(source_ty, &[target_ty])
}); });
match fulfill_obligation(scx, DUMMY_SP, trait_ref) { match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
@ -848,7 +848,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
common::validate_substs(instance.substs); common::validate_substs(instance.substs);
(instance.substs, Some(instance.def)) (instance.substs, Some(instance.def))
} }
None => (Substs::empty(ccx.tcx()), None) None => (ccx.tcx().intern_substs(&[]), None)
}; };
let local_id = def_id.and_then(|id| ccx.tcx().map.as_local_node_id(id)); let local_id = def_id.and_then(|id| ccx.tcx().map.as_local_node_id(id));
@ -1211,7 +1211,7 @@ pub fn maybe_create_entry_wrapper(ccx: &CrateContext) {
Ok(id) => id, Ok(id) => id,
Err(s) => ccx.sess().fatal(&s) Err(s) => ccx.sess().fatal(&s)
}; };
let empty_substs = Substs::empty(ccx.tcx()); let empty_substs = ccx.tcx().intern_substs(&[]);
let start_fn = Callee::def(ccx, start_def_id, empty_substs).reify(ccx); let start_fn = Callee::def(ccx, start_def_id, empty_substs).reify(ccx);
let args = { let args = {
let opaque_rust_main = let opaque_rust_main =

View File

@ -327,7 +327,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
} }
}; };
let sig = tcx.erase_late_bound_regions_and_normalize(sig); let sig = tcx.erase_late_bound_regions_and_normalize(sig);
let tuple_input_ty = tcx.mk_tup(&sig.inputs); let tuple_input_ty = tcx.intern_tup(&sig.inputs[..]);
let sig = ty::FnSig { let sig = ty::FnSig {
inputs: vec![bare_fn_ty_maybe_ref, inputs: vec![bare_fn_ty_maybe_ref,
tuple_input_ty], tuple_input_ty],

View File

@ -732,7 +732,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
create_fn_trans_item(scx, create_fn_trans_item(scx,
exchange_free_fn_def_id, exchange_free_fn_def_id,
fn_substs, fn_substs,
Substs::empty(scx.tcx())); scx.tcx().intern_substs(&[]));
output.push(exchange_free_fn_trans_item); output.push(exchange_free_fn_trans_item);
} }
@ -752,7 +752,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
.drop_trait() .drop_trait()
.unwrap(); .unwrap();
let self_type_substs = Substs::new_trait(scx.tcx(), ty, &[]); let self_type_substs = scx.tcx().mk_substs_trait(ty, &[]);
let trait_ref = ty::TraitRef { let trait_ref = ty::TraitRef {
def_id: drop_trait_def_id, def_id: drop_trait_def_id,
@ -768,7 +768,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
let trans_item = create_fn_trans_item(scx, let trans_item = create_fn_trans_item(scx,
destructor_did, destructor_did,
substs, substs,
Substs::empty(scx.tcx())); scx.tcx().intern_substs(&[]));
output.push(trans_item); output.push(trans_item);
} }
@ -1035,7 +1035,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a,
if let ty::TyTrait(ref trait_ty) = trait_ty.sty { if let ty::TyTrait(ref trait_ty) = trait_ty.sty {
let poly_trait_ref = trait_ty.principal.with_self_ty(scx.tcx(), impl_ty); let poly_trait_ref = trait_ty.principal.with_self_ty(scx.tcx(), impl_ty);
let param_substs = Substs::empty(scx.tcx()); let param_substs = scx.tcx().intern_substs(&[]);
// Walk all methods of the trait, including those of its supertraits // Walk all methods of the trait, including those of its supertraits
let methods = traits::get_vtable_methods(scx.tcx(), poly_trait_ref); let methods = traits::get_vtable_methods(scx.tcx(), poly_trait_ref);

View File

@ -376,7 +376,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
let tcx = ccx.tcx(); let tcx = ccx.tcx();
match tcx.lang_items.eh_personality() { match tcx.lang_items.eh_personality() {
Some(def_id) if !base::wants_msvc_seh(ccx.sess()) => { Some(def_id) if !base::wants_msvc_seh(ccx.sess()) => {
Callee::def(ccx, def_id, Substs::empty(tcx)).reify(ccx) Callee::def(ccx, def_id, tcx.intern_substs(&[])).reify(ccx)
} }
_ => { _ => {
if let Some(llpersonality) = ccx.eh_personality().get() { if let Some(llpersonality) = ccx.eh_personality().get() {
@ -403,7 +403,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
let tcx = ccx.tcx(); let tcx = ccx.tcx();
assert!(ccx.sess().target.target.options.custom_unwind_resume); assert!(ccx.sess().target.target.options.custom_unwind_resume);
if let Some(def_id) = tcx.lang_items.eh_unwind_resume() { if let Some(def_id) = tcx.lang_items.eh_unwind_resume() {
return Callee::def(ccx, def_id, Substs::empty(tcx)); return Callee::def(ccx, def_id, tcx.intern_substs(&[]));
} }
let ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy { let ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {

View File

@ -48,7 +48,7 @@ pub fn trans_exchange_free_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let def_id = langcall(bcx.tcx(), None, "", ExchangeFreeFnLangItem); let def_id = langcall(bcx.tcx(), None, "", ExchangeFreeFnLangItem);
let args = [PointerCast(bcx, v, Type::i8p(bcx.ccx())), size, align]; let args = [PointerCast(bcx, v, Type::i8p(bcx.ccx())), size, align];
Callee::def(bcx.ccx(), def_id, Substs::empty(bcx.tcx())) Callee::def(bcx.ccx(), def_id, bcx.tcx().intern_substs(&[]))
.call(bcx, debug_loc, &args, None).bcx .call(bcx, debug_loc, &args, None).bcx
} }
@ -292,7 +292,7 @@ fn trans_custom_dtor<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let trait_ref = ty::Binder(ty::TraitRef { let trait_ref = ty::Binder(ty::TraitRef {
def_id: tcx.lang_items.drop_trait().unwrap(), def_id: tcx.lang_items.drop_trait().unwrap(),
substs: Substs::new_trait(tcx, t, &[]) substs: tcx.mk_substs_trait(t, &[])
}); });
let vtbl = match fulfill_obligation(bcx.ccx().shared(), DUMMY_SP, trait_ref) { let vtbl = match fulfill_obligation(bcx.ccx().shared(), DUMMY_SP, trait_ref) {
traits::VtableImpl(data) => data, traits::VtableImpl(data) => data,

View File

@ -773,7 +773,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
let rhs = self.const_operand(rhs, span)?; let rhs = self.const_operand(rhs, span)?;
let ty = lhs.ty; let ty = lhs.ty;
let val_ty = op.ty(tcx, lhs.ty, rhs.ty); let val_ty = op.ty(tcx, lhs.ty, rhs.ty);
let binop_ty = tcx.mk_tup(&[val_ty, tcx.types.bool]); let binop_ty = tcx.intern_tup(&[val_ty, tcx.types.bool]);
let (lhs, rhs) = (lhs.llval, rhs.llval); let (lhs, rhs) = (lhs.llval, rhs.llval);
assert!(!ty.is_fp()); assert!(!ty.is_fp());

View File

@ -430,7 +430,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
lhs.immediate(), rhs.immediate(), lhs.immediate(), rhs.immediate(),
lhs.ty); lhs.ty);
let val_ty = op.ty(bcx.tcx(), lhs.ty, rhs.ty); let val_ty = op.ty(bcx.tcx(), lhs.ty, rhs.ty);
let operand_ty = bcx.tcx().mk_tup(&[val_ty, bcx.tcx().types.bool]); let operand_ty = bcx.tcx().intern_tup(&[val_ty, bcx.tcx().types.bool]);
let operand = OperandRef { let operand = OperandRef {
val: result, val: result,
ty: operand_ty ty: operand_ty

View File

@ -310,7 +310,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
}, },
TransItem::Static(node_id) => { TransItem::Static(node_id) => {
let def_id = hir_map.local_def_id(node_id); let def_id = hir_map.local_def_id(node_id);
let instance = Instance::new(def_id, Substs::empty(tcx)); let instance = Instance::new(def_id, tcx.intern_substs(&[]));
to_string_internal(tcx, "static ", instance) to_string_internal(tcx, "static ", instance)
}, },
}; };

View File

@ -635,9 +635,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
{ {
let anon_scope = rscope.anon_type_scope(); let anon_scope = rscope.anon_type_scope();
let binding_rscope = MaybeWithAnonTypes::new(BindingRscope::new(), anon_scope); let binding_rscope = MaybeWithAnonTypes::new(BindingRscope::new(), anon_scope);
let inputs: Vec<_> = data.inputs.iter().map(|a_t| { let inputs = self.tcx().mk_type_list(data.inputs.iter().map(|a_t| {
self.ast_ty_arg_to_ty(&binding_rscope, None, region_substs, a_t) self.ast_ty_arg_to_ty(&binding_rscope, None, region_substs, a_t)
}).collect(); }));
let inputs_len = inputs.len(); let inputs_len = inputs.len();
let input_params = || vec![String::new(); inputs_len]; let input_params = || vec![String::new(); inputs_len];
let implied_output_region = self.find_implied_output_region(&inputs, input_params); let implied_output_region = self.find_implied_output_region(&inputs, input_params);
@ -660,7 +660,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
span: output_span span: output_span
}; };
(self.tcx().mk_tup(&inputs), output_binding) (self.tcx().mk_ty(ty::TyTuple(inputs)), output_binding)
} }
pub fn instantiate_poly_trait_ref(&self, pub fn instantiate_poly_trait_ref(&self,
@ -1661,10 +1661,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
tcx.types.never tcx.types.never
}, },
hir::TyTup(ref fields) => { hir::TyTup(ref fields) => {
let flds = fields.iter() tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(rscope, &t)))
.map(|t| self.ast_ty_to_ty(rscope, &t))
.collect::<Vec<_>>();
tcx.mk_tup(&flds)
} }
hir::TyBareFn(ref bf) => { hir::TyBareFn(ref bf) => {
require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);

View File

@ -168,8 +168,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} }
let max_len = cmp::max(expected_len, elements.len()); let max_len = cmp::max(expected_len, elements.len());
let element_tys: Vec<_> = (0 .. max_len).map(|_| self.next_ty_var()).collect(); let element_tys_iter = (0..max_len).map(|_| self.next_ty_var());
let pat_ty = tcx.mk_tup(&element_tys); let element_tys = tcx.mk_type_list(element_tys_iter);
let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys));
self.demand_eqtype(pat.span, expected, pat_ty); self.demand_eqtype(pat.span, expected, pat_ty);
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
self.check_pat(elem, &element_tys[i]); self.check_pat(elem, &element_tys[i]);

View File

@ -16,7 +16,6 @@ use rustc::traits;
use rustc::ty::{self, Ty, TraitRef}; use rustc::ty::{self, Ty, TraitRef};
use rustc::ty::{ToPredicate, TypeFoldable}; use rustc::ty::{ToPredicate, TypeFoldable};
use rustc::ty::{MethodCall, MethodCallee}; use rustc::ty::{MethodCall, MethodCallee};
use rustc::ty::subst::Substs;
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue}; use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
use rustc::hir; use rustc::hir;
@ -106,7 +105,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
Some(f) => f, Some(f) => f,
None => return None, None => return None,
}, },
substs: Substs::new_trait(tcx, self.cur_ty, &[]), substs: tcx.mk_substs_trait(self.cur_ty, &[]),
}; };
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);

View File

@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Tuple up the arguments and insert the resulting function type into // Tuple up the arguments and insert the resulting function type into
// the `closures` table. // the `closures` table.
fn_ty.sig.0.inputs = vec![self.tcx.mk_tup(&fn_ty.sig.0.inputs)]; fn_ty.sig.0.inputs = vec![self.tcx.intern_tup(&fn_ty.sig.0.inputs[..])];
debug!("closure for {:?} --> sig={:?} opt_kind={:?}", debug!("closure for {:?} --> sig={:?} opt_kind={:?}",
expr_def_id, expr_def_id,

View File

@ -89,7 +89,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) {
"cxchg" | "cxchgweak" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), "cxchg" | "cxchgweak" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)),
param(ccx, 0), param(ccx, 0),
param(ccx, 0)), param(ccx, 0)),
tcx.mk_tup(&[param(ccx, 0), tcx.types.bool])), tcx.intern_tup(&[param(ccx, 0), tcx.types.bool])),
"load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))), "load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))),
param(ccx, 0)), param(ccx, 0)),
"store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)), "store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)),
@ -274,7 +274,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) {
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" =>
(1, vec!(param(ccx, 0), param(ccx, 0)), (1, vec!(param(ccx, 0), param(ccx, 0)),
tcx.mk_tup(&[param(ccx, 0), tcx.types.bool])), tcx.intern_tup(&[param(ccx, 0), tcx.types.bool])),
"unchecked_div" | "unchecked_rem" => "unchecked_div" | "unchecked_rem" =>
(1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)), (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),

View File

@ -19,7 +19,6 @@ use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable};
use hir::def::Def; use hir::def::Def;
use hir::def_id::{CRATE_DEF_INDEX, DefId}; use hir::def_id::{CRATE_DEF_INDEX, DefId};
use middle::lang_items::FnOnceTraitLangItem; use middle::lang_items::FnOnceTraitLangItem;
use rustc::ty::subst::Substs;
use rustc::traits::{Obligation, SelectionContext}; use rustc::traits::{Obligation, SelectionContext};
use util::nodemap::FnvHashSet; use util::nodemap::FnvHashSet;
@ -55,7 +54,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.autoderef(span, ty).any(|(ty, _)| { self.autoderef(span, ty).any(|(ty, _)| {
self.probe(|_| { self.probe(|_| {
let fn_once_substs = Substs::new_trait(tcx, ty, &[self.next_ty_var()]); let fn_once_substs = tcx.mk_substs_trait(ty, &[self.next_ty_var()]);
let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
let poly_trait_ref = trait_ref.to_poly_trait_ref(); let poly_trait_ref = trait_ref.to_poly_trait_ref();
let obligation = let obligation =

View File

@ -2380,7 +2380,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let err_inputs = match tuple_arguments { let err_inputs = match tuple_arguments {
DontTupleArguments => err_inputs, DontTupleArguments => err_inputs,
TupleArguments => vec![self.tcx.mk_tup(&err_inputs)], TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
}; };
self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr, self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
@ -3718,9 +3718,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
_ => None _ => None
} }
}); });
let mut err_field = false;
let elt_ts = elts.iter().enumerate().map(|(i, e)| { let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| {
let t = match flds { let t = match flds {
Some(ref fs) if i < fs.len() => { Some(ref fs) if i < fs.len() => {
let ety = fs[i]; let ety = fs[i];
@ -3731,13 +3730,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.check_expr_with_expectation(&e, NoExpectation) self.check_expr_with_expectation(&e, NoExpectation)
} }
}; };
err_field = err_field || t.references_error();
t t
}).collect::<Vec<_>>(); });
if err_field { let tuple = tcx.mk_tup(elt_ts_iter);
if tuple.references_error() {
tcx.types.err tcx.types.err
} else { } else {
tcx.mk_tup(&elt_ts) tuple
} }
} }
hir::ExprStruct(ref path, ref fields, ref base_expr) => { hir::ExprStruct(ref path, ref fields, ref base_expr) => {
@ -4193,7 +4192,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let ty = self.normalize_associated_types_in(span, &ty); let ty = self.normalize_associated_types_in(span, &ty);
self.write_ty(node_id, ty); self.write_ty(node_id, ty);
self.write_substs(node_id, ty::ItemSubsts { self.write_substs(node_id, ty::ItemSubsts {
substs: Substs::empty(self.tcx) substs: self.tcx.intern_substs(&[])
}); });
return ty; return ty;
} }

View File

@ -233,7 +233,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
_ => () _ => ()
} }
let main_def_id = tcx.map.local_def_id(main_id); let main_def_id = tcx.map.local_def_id(main_id);
let substs = Substs::empty(tcx); let substs = tcx.intern_substs(&[]);
let se_ty = tcx.mk_fn_def(main_def_id, substs, let se_ty = tcx.mk_fn_def(main_def_id, substs,
tcx.mk_bare_fn(ty::BareFnTy { tcx.mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Normal, unsafety: hir::Unsafety::Normal,
@ -285,7 +285,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
} }
let start_def_id = ccx.tcx.map.local_def_id(start_id); let start_def_id = ccx.tcx.map.local_def_id(start_id);
let substs = Substs::empty(tcx); let substs = tcx.intern_substs(&[]);
let se_ty = tcx.mk_fn_def(start_def_id, substs, let se_ty = tcx.mk_fn_def(start_def_id, substs,
tcx.mk_bare_fn(ty::BareFnTy { tcx.mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Normal, unsafety: hir::Unsafety::Normal,

View File

@ -670,7 +670,7 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
Some(tcx) => tcx, Some(tcx) => tcx,
None => return RegionBound(Lifetime::statik()) None => return RegionBound(Lifetime::statik())
}; };
let empty = Substs::empty(tcx); let empty = tcx.intern_substs(&[]);
let (did, path) = match *self { let (did, path) = match *self {
ty::BoundSend => ty::BoundSend =>
(tcx.lang_items.send_trait().unwrap(), (tcx.lang_items.send_trait().unwrap(),