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
/// reference to it. Will panic if passed a zero-sized types.
///
/// Panics:
/// - Zero-sized types
/// - Zero-length slices
#[inline]
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
where T: Copy {
assert!(mem::size_of::<T>() != 0);
if slice.len() == 0 {
return unsafe { slice::from_raw_parts_mut(heap::EMPTY as *mut T, 0) };
}
assert!(slice.len() != 0);
let available_capacity_bytes = self.end.get() as usize - self.ptr.get() as usize;
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 rhs_ty = rhs.ty(mir, tcx);
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)
}
&Rvalue::UnaryOp(_, ref operand) => {
@ -184,7 +184,7 @@ impl<'tcx> Rvalue<'tcx> {
}
AggregateKind::Tuple => {
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, _) => {

View File

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

View File

@ -2599,7 +2599,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
k
}
});
let substs = Substs::new(tcx, params);
let substs = tcx.mk_substs(params);
for &ty in fields.split_last().unwrap().1 {
if ty.subst(tcx, substs).references_error() {
return Err(Unimplemented);
@ -2619,7 +2619,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
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 InferOk { obligations, .. } =
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(ty::TraitRef {
def_id: def_id,
substs: Substs::new_trait(self, param_ty, &[])
substs: self.mk_substs_trait(param_ty, &[])
})
}
Err(e) => {
@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
let trait_ref = ty::TraitRef {
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)
}
@ -486,11 +486,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
let arguments_tuple = match tuple_arguments {
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 {
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))
}

View File

@ -36,6 +36,7 @@ use ty::maps;
use util::common::MemoizationMap;
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
use util::nodemap::{FnvHashMap, FnvHashSet};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use arena::TypedArena;
use std::borrow::Borrow;
@ -44,6 +45,7 @@ use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use std::iter;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
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> {
type Lifted = &'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 *self as *const _ == substs as *const _ {
return Some(substs);
@ -859,6 +864,9 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice<Ty<'a>> {
type Lifted = &'tcx Slice<Ty<'tcx>>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, '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 *self as *const _ == list as *const _ {
return Some(list);
@ -1212,8 +1220,8 @@ macro_rules! slice_interners {
}
slice_interners!(
type_list: mk_type_list(Ty),
substs: mk_substs(Kind)
type_list: _intern_type_list(Ty),
substs: _intern_substs(Kind)
);
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))
}
pub fn mk_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
self.mk_ty(TyTuple(self.mk_type_list(ts)))
pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
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> {
self.mk_tup(&[])
self.intern_tup(&[])
}
pub fn mk_diverging_default(self) -> Ty<'tcx> {
@ -1369,7 +1381,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-> Ty<'tcx> {
self.mk_closure_from_closure_substs(closure_id, ClosureSubsts {
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))
}
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>>> {
self.trait_items_cache.memoize(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::slice;
use std::vec::IntoIter;
use std::mem;
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
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<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
/// the original var id (that is, the root variable that is referenced
/// 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,
0 => tcx.types.bool,
1 => tys[0],
_ => tcx.mk_tup(&tys)
_ => tcx.intern_tup(&tys[..])
};
match self.sized_constraint.get(dep_node()) {
@ -1873,7 +1882,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
};
let sized_predicate = Binder(TraitRef {
def_id: sized_trait,
substs: Substs::new_trait(tcx, ty, &[])
substs: tcx.mk_substs_trait(ty, &[])
}).to_predicate();
let predicates = tcx.lookup_predicates(self.did).predicates;
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> {
match self.tables.borrow().item_substs.get(&id) {
None => ItemSubsts {
substs: Substs::empty(self.global_tcx())
substs: self.global_tcx().intern_substs(&[])
},
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
let free_id_outlive = self.region_maps.node_extent(ast::DUMMY_NODE_ID);
ty::ParameterEnvironment {
free_substs: Substs::empty(self),
free_substs: self.intern_substs(&[]),
caller_bounds: Vec::new(),
implicit_region_bound: self.mk_region(ty::ReEmpty),
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)
}
/// 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`.
fn relate_with_variance<T: Relate<'tcx>>(&mut self,
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> {
@ -489,10 +483,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
(&ty::TyTuple(as_), &ty::TyTuple(bs)) =>
{
if as_.len() == bs.len() {
let ts = as_.iter().zip(bs)
.map(|(a, b)| relation.relate(a, b))
.collect::<Result<Vec<_>, _>>()?;
Ok(tcx.mk_tup(&ts))
Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?)
} else if !(as_.is_empty() || bs.is_empty()) {
Err(TypeError::TupleSize(
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
{
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 {
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 ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use std::rc::Rc;
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>> {
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<_>>();
folder.tcx().mk_type_list(&tys)
let v = self.iter().map(|t| t.fold_with(folder)).collect::<AccumulateVec<[_; 8]>>();
folder.tcx().intern_type_list(&v)
}
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 syntax_pos::{Span, DUMMY_SP};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use core::nonzero::NonZero;
use std::fmt;
@ -164,31 +165,6 @@ impl<'tcx> Decodable for Kind<'tcx> {
pub type Substs<'tcx> = Slice<Kind<'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,
/// by calling closures to obtain each region and type.
/// 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> {
let defs = tcx.lookup_generics(def_id);
let mut substs = Vec::with_capacity(defs.count());
Substs::fill_item(&mut substs, tcx, defs, &mut mk_region, &mut mk_type);
Substs::new(tcx, substs)
tcx.intern_substs(&substs)
}
fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
@ -298,20 +272,20 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
target_substs: &Substs<'tcx>)
-> &'tcx Substs<'tcx> {
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> {
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
// calling `mk_substs` and instead reuse the existing substs.
if params[..] == self[..] {
self
} 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> {
let defs = tcx.lookup_generics(trait_id);
let params = substs[..defs.own_count()].iter().cloned();
ty::TraitRef {
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.
trait_ref.substs.type_at(0);
let params = trait_ref.substs[1..].iter().cloned();
ty::ExistentialTraitRef {
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());
self.map_bound(|trait_ref| {
let params = trait_ref.substs.iter().cloned();
let params = iter::once(Kind::from(self_ty)).chain(params);
ty::TraitRef {
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.
use hir::def_id::DefId;
use ty::subst::{self, Subst, Substs};
use ty::subst::{self, Subst};
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
use ty::{TyBool, TyChar, TyAdt};
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.
let item_predicates = tcx.lookup_predicates(def_id);
let substs = tcx.lift(&substs).unwrap_or_else(|| {
Substs::empty(tcx)
tcx.intern_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 free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
.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);
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::resolve_lifetime;
use rustc::middle::stability;
use rustc::ty::subst::{Kind, Subst, Substs};
use rustc::ty::subst::{Kind, Subst};
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
use rustc_metadata::cstore::CStore;
use rustc::hir::map as hir_map;
use rustc::session::{self, config};
use std::iter;
use std::rc::Rc;
use syntax::ast;
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> {
self.infcx.tcx.mk_tup(&[ty1, ty2])
self.infcx.tcx.intern_tup(&[ty1, ty2])
}
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())
};
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);
// 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()))
};
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);
// 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())
};
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);
// t_expected = fn(&'a isize)
@ -803,8 +802,8 @@ fn walk_ty() {
let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize;
let uint_ty = tcx.types.usize;
let tup1_ty = tcx.mk_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.mk_tup(&[tup1_ty, tup1_ty, uint_ty]);
let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]);
let uniq_ty = tcx.mk_box(tup2_ty);
let walked: Vec<_> = uniq_ty.walk().collect();
assert_eq!(walked,
@ -819,8 +818,8 @@ fn walk_ty_skip_subtree() {
let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize;
let uint_ty = tcx.types.usize;
let tup1_ty = tcx.mk_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.mk_tup(&[tup1_ty, tup1_ty, uint_ty]);
let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]);
let uniq_ty = tcx.mk_box(tup2_ty);
// types we expect to see (in order), plus a boolean saying

View File

@ -503,21 +503,21 @@ impl LateLintPass for MissingCopyImplementations {
return;
}
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) => {
if ast_generics.is_parameterized() {
return;
}
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) => {
if ast_generics.is_parameterized() {
return;
}
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,
};

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> {
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> {
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 bool_ty = self.hir.bool_ty();
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);
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 rustc::middle::region::{CodeExtent, CodeExtentData};
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::mir::repr::*;
use syntax_pos::Span;
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::fnv::FnvHashMap;
use std::iter;
pub struct Scope<'tcx> {
/// the scope-id within the scope_auxiliary
id: ScopeId,
@ -800,7 +798,7 @@ fn build_free<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-> TerminatorKind<'tcx> {
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
.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 {
func: Operand::Constant(Constant {
span: data.span,

View File

@ -27,7 +27,7 @@ use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::FnKind;
use rustc::hir::map::blocks::FnLikeNode;
use rustc::infer::InferCtxt;
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::subst::Subst;
use rustc::ty::{self, Ty, TyCtxt};
use syntax::parse::token;
use rustc::hir;
@ -146,7 +146,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
params: &[Ty<'tcx>])
-> (Ty<'tcx>, Literal<'tcx>) {
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() {
match *trait_item {
ty::ImplOrTraitItem::MethodTraitItem(ref method) => {

View File

@ -214,7 +214,7 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Allocate space:
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);
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 {
let trait_ref = ty::Binder(ty::TraitRef {
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) {
@ -848,7 +848,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
common::validate_substs(instance.substs);
(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));
@ -1211,7 +1211,7 @@ pub fn maybe_create_entry_wrapper(ccx: &CrateContext) {
Ok(id) => id,
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 args = {
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 tuple_input_ty = tcx.mk_tup(&sig.inputs);
let tuple_input_ty = tcx.intern_tup(&sig.inputs[..]);
let sig = ty::FnSig {
inputs: vec![bare_fn_ty_maybe_ref,
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,
exchange_free_fn_def_id,
fn_substs,
Substs::empty(scx.tcx()));
scx.tcx().intern_substs(&[]));
output.push(exchange_free_fn_trans_item);
}
@ -752,7 +752,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
.drop_trait()
.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 {
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,
destructor_did,
substs,
Substs::empty(scx.tcx()));
scx.tcx().intern_substs(&[]));
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 {
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
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();
match tcx.lang_items.eh_personality() {
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() {
@ -403,7 +403,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
let tcx = ccx.tcx();
assert!(ccx.sess().target.target.options.custom_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 {

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 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
}
@ -292,7 +292,7 @@ fn trans_custom_dtor<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let trait_ref = ty::Binder(ty::TraitRef {
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) {
traits::VtableImpl(data) => data,

View File

@ -773,7 +773,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
let rhs = self.const_operand(rhs, span)?;
let ty = lhs.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);
assert!(!ty.is_fp());

View File

@ -430,7 +430,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
lhs.immediate(), rhs.immediate(),
lhs.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 {
val: result,
ty: operand_ty

View File

@ -310,7 +310,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
},
TransItem::Static(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)
},
};

View File

@ -635,9 +635,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
{
let anon_scope = rscope.anon_type_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)
}).collect();
}));
let inputs_len = inputs.len();
let input_params = || vec![String::new(); inputs_len];
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
};
(self.tcx().mk_tup(&inputs), output_binding)
(self.tcx().mk_ty(ty::TyTuple(inputs)), output_binding)
}
pub fn instantiate_poly_trait_ref(&self,
@ -1661,10 +1661,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
tcx.types.never
},
hir::TyTup(ref fields) => {
let flds = fields.iter()
.map(|t| self.ast_ty_to_ty(rscope, &t))
.collect::<Vec<_>>();
tcx.mk_tup(&flds)
tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(rscope, &t)))
}
hir::TyBareFn(ref bf) => {
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 element_tys: Vec<_> = (0 .. max_len).map(|_| self.next_ty_var()).collect();
let pat_ty = tcx.mk_tup(&element_tys);
let element_tys_iter = (0..max_len).map(|_| self.next_ty_var());
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);
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
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::{ToPredicate, TypeFoldable};
use rustc::ty::{MethodCall, MethodCallee};
use rustc::ty::subst::Substs;
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
use rustc::hir;
@ -106,7 +105,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
Some(f) => f,
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);

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
// 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={:?}",
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)),
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))),
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" =>
(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" =>
(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_id::{CRATE_DEF_INDEX, DefId};
use middle::lang_items::FnOnceTraitLangItem;
use rustc::ty::subst::Substs;
use rustc::traits::{Obligation, SelectionContext};
use util::nodemap::FnvHashSet;
@ -55,7 +54,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.autoderef(span, ty).any(|(ty, _)| {
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 poly_trait_ref = trait_ref.to_poly_trait_ref();
let obligation =

View File

@ -2380,7 +2380,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let err_inputs = match tuple_arguments {
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,
@ -3718,9 +3718,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
_ => 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 {
Some(ref fs) if i < fs.len() => {
let ety = fs[i];
@ -3731,13 +3730,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.check_expr_with_expectation(&e, NoExpectation)
}
};
err_field = err_field || t.references_error();
t
}).collect::<Vec<_>>();
if err_field {
});
let tuple = tcx.mk_tup(elt_ts_iter);
if tuple.references_error() {
tcx.types.err
} else {
tcx.mk_tup(&elt_ts)
tuple
}
}
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);
self.write_ty(node_id, ty);
self.write_substs(node_id, ty::ItemSubsts {
substs: Substs::empty(self.tcx)
substs: self.tcx.intern_substs(&[])
});
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 substs = Substs::empty(tcx);
let substs = tcx.intern_substs(&[]);
let se_ty = tcx.mk_fn_def(main_def_id, substs,
tcx.mk_bare_fn(ty::BareFnTy {
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 substs = Substs::empty(tcx);
let substs = tcx.intern_substs(&[]);
let se_ty = tcx.mk_fn_def(start_def_id, substs,
tcx.mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Normal,

View File

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