rustc: reduce Substs and Generics to a simple immutable API.

This commit is contained in:
Eduard Burtescu 2016-08-08 23:39:49 +03:00
parent bfdfa1ce1d
commit 4158673ad7
80 changed files with 1226 additions and 1548 deletions

View File

@ -1366,7 +1366,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
hir::TyPath(ref maybe_qself, ref path) => {
match self.tcx.expect_def(cur_ty.id) {
Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => {
let generics = self.tcx.lookup_item_type(did).generics;
let generics = self.tcx.lookup_generics(did);
let expected =
generics.regions.len(subst::TypeSpace) as u32;

View File

@ -25,9 +25,7 @@ use middle::mem_categorization as mc;
use middle::mem_categorization::McResult;
use middle::region::CodeExtent;
use mir::tcx::LvalueTy;
use ty::subst;
use ty::subst::Substs;
use ty::subst::Subst;
use ty::subst::{Subst, Substs};
use ty::adjustment;
use ty::{TyVid, IntVid, FloatVid};
use ty::{self, Ty, TyCtxt};
@ -1236,43 +1234,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
/// type/region parameter to a fresh inference variable.
pub fn fresh_substs_for_generics(&self,
span: Span,
generics: &ty::Generics<'tcx>)
-> &'tcx subst::Substs<'tcx>
{
let substs = Substs::from_generics(generics, |def, _| {
pub fn fresh_substs_for_item(&self,
span: Span,
def_id: DefId)
-> &'tcx Substs<'tcx> {
Substs::for_item(self.tcx, def_id, |def, _| {
self.region_var_for_def(span, def)
}, |def, substs| {
self.type_var_for_def(span, def, substs)
});
self.tcx.mk_substs(substs)
}
/// Given a set of generics defined on a trait, returns a substitution mapping each output
/// type/region parameter to a fresh inference variable, and mapping the self type to
/// `self_ty`.
pub fn fresh_substs_for_trait(&self,
span: Span,
generics: &ty::Generics<'tcx>,
self_ty: Ty<'tcx>)
-> &'tcx subst::Substs<'tcx>
{
assert!(generics.types.len(subst::SelfSpace) == 1);
assert!(generics.types.len(subst::FnSpace) == 0);
let substs = Substs::from_generics(generics, |def, _| {
self.region_var_for_def(span, def)
}, |def, substs| {
if def.space == subst::SelfSpace {
self_ty
} else {
self.type_var_for_def(span, def, substs)
}
});
self.tcx.mk_substs(substs)
})
}
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {

View File

@ -154,7 +154,7 @@ pub trait CrateStore<'tcx> {
fn item_variances(&self, def: DefId) -> ty::ItemVariances;
fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr>;
fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::TypeScheme<'tcx>;
-> Ty<'tcx>;
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>>;
fn item_name(&self, def: DefId) -> ast::Name;
fn opt_item_name(&self, def: DefId) -> Option<ast::Name>;
@ -162,6 +162,8 @@ pub trait CrateStore<'tcx> {
-> ty::GenericPredicates<'tcx>;
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::GenericPredicates<'tcx>;
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> &'tcx ty::Generics<'tcx>;
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
@ -187,8 +189,7 @@ pub trait CrateStore<'tcx> {
fn impl_parent(&self, impl_def_id: DefId) -> Option<DefId>;
// trait/impl-item info
fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
-> Option<DefId>;
fn trait_of_item(&self, def_id: DefId) -> Option<DefId>;
fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<ty::ImplOrTraitItem<'tcx>>;
@ -334,7 +335,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn item_variances(&self, def: DefId) -> ty::ItemVariances { bug!("item_variances") }
fn repr_attrs(&self, def: DefId) -> Vec<attr::ReprAttr> { bug!("repr_attrs") }
fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::TypeScheme<'tcx> { bug!("item_type") }
-> Ty<'tcx> { bug!("item_type") }
fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap<DefId>> {
bug!("visible_parent_map")
}
@ -344,6 +345,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
-> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> &'tcx ty::Generics<'tcx> { bug!("item_generics") }
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
{ bug!("trait_def") }
@ -379,8 +382,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn impl_parent(&self, def: DefId) -> Option<DefId> { bug!("impl_parent") }
// trait/impl-item info
fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
-> Option<DefId> { bug!("trait_of_item") }
fn trait_of_item(&self, def_id: DefId) -> Option<DefId> { bug!("trait_of_item") }
fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<ty::ImplOrTraitItem<'tcx>> { bug!("impl_or_trait_item") }
@ -583,7 +585,7 @@ pub mod tls {
pub trait DecodingContext<'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx>;
fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx>;
fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> &'tcx Substs<'tcx>;
fn translate_def_id(&self, def_id: DefId) -> DefId;
}

View File

@ -18,7 +18,7 @@ use hir::{self, pat_util, PatKind};
use hir::intravisit::{self, Visitor};
use middle::privacy;
use ty::{self, TyCtxt};
use ty::{self, subst, TyCtxt};
use hir::def::Def;
use hir::def_id::{DefId};
use lint;
@ -88,15 +88,24 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn lookup_and_handle_definition(&mut self, id: ast::NodeId) {
use ty::TypeVariants::{TyEnum, TyStruct};
// If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar`
self.tcx.tables.borrow().item_substs.get(&id)
.and_then(|substs| substs.substs.self_ty())
.map(|ty| match ty.sty {
TyEnum(tyid, _) | TyStruct(tyid, _) => self.check_def_id(tyid.did),
_ => (),
});
let def = self.tcx.expect_def(id);
// If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar`
match def {
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
if self.tcx.trait_of_item(def.def_id()).is_some() => {
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
match substs.substs.types.get(subst::SelfSpace, 0).sty {
TyEnum(tyid, _) | TyStruct(tyid, _) => {
self.check_def_id(tyid.did)
}
_ => {}
}
}
}
_ => {}
}
match def {
Def::Const(_) | Def::AssociatedConst(..) => {
self.check_def_id(def.def_id());

View File

@ -1073,10 +1073,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
let variant_def = &adt_def.variants[variant];
ppaux::parameterized(fmt, substs, variant_def.did,
ppaux::Ns::Value, &[],
|tcx| {
Some(tcx.lookup_item_type(variant_def.did).generics)
})?;
ppaux::Ns::Value, &[])?;
match variant_def.kind {
ty::VariantKind::Unit => Ok(()),
@ -1169,9 +1166,7 @@ impl<'tcx> Debug for Literal<'tcx> {
use self::Literal::*;
match *self {
Item { def_id, substs } => {
ppaux::parameterized(
fmt, substs, def_id, ppaux::Ns::Value, &[],
|tcx| Some(tcx.lookup_item_type(def_id).generics))
ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[])
}
Value { ref value } => {
write!(fmt, "const ")?;

View File

@ -221,9 +221,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.tcx.lookup_trait_def(trait_ref.def_id)
.for_each_relevant_impl(self.tcx, trait_self_ty, |def_id| {
let ity = tcx.lookup_item_type(def_id);
let impl_substs = self.fresh_substs_for_generics(obligation.cause.span,
&ity.generics);
let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
let impl_trait_ref = tcx
.impl_trait_ref(def_id)
.unwrap()

View File

@ -160,10 +160,9 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> {
// We can resolve the `impl Trait` to its concrete type.
if let Some(ty_scheme) = tcx.opt_lookup_item_type(def_id) {
let concrete_ty = ty_scheme.ty.subst(tcx, substs);
let concrete_substs = Substs::new_trait(vec![], vec![], concrete_ty);
let predicate = ty::TraitRef {
def_id: self.predicate.def_id(),
substs: tcx.mk_substs(concrete_substs)
substs: Substs::new_trait(tcx, vec![], vec![], concrete_ty)
}.to_predicate();
let original_obligation = Obligation::new(self.cause.clone(),

View File

@ -17,7 +17,7 @@ pub use self::ObligationCauseCode::*;
use hir::def_id::DefId;
use middle::free_region::FreeRegionMap;
use ty::subst;
use ty::subst::Substs;
use ty::{self, Ty, TyCtxt, TypeFoldable};
use infer::InferCtxt;
@ -272,7 +272,7 @@ pub enum Vtable<'tcx, N> {
#[derive(Clone, PartialEq, Eq)]
pub struct VtableImplData<'tcx, N> {
pub impl_def_id: DefId,
pub substs: &'tcx subst::Substs<'tcx>,
pub substs: &'tcx Substs<'tcx>,
pub nested: Vec<N>
}

View File

@ -166,25 +166,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
fn trait_has_sized_self(self, trait_def_id: DefId) -> bool {
let trait_def = self.lookup_trait_def(trait_def_id);
let trait_predicates = self.lookup_predicates(trait_def_id);
self.generics_require_sized_self(&trait_def.generics, &trait_predicates)
self.generics_require_sized_self(trait_def_id)
}
fn generics_require_sized_self(self,
generics: &ty::Generics<'gcx>,
predicates: &ty::GenericPredicates<'gcx>)
-> bool
{
fn generics_require_sized_self(self, def_id: DefId) -> bool {
let sized_def_id = match self.lang_items.sized_trait() {
Some(def_id) => def_id,
None => { return false; /* No Sized trait, can't require it! */ }
};
// Search for a predicate like `Self : Sized` amongst the trait bounds.
let free_substs = self.construct_free_substs(generics,
let free_substs = self.construct_free_substs(def_id,
self.region_maps.node_extent(ast::DUMMY_NODE_ID));
let predicates = predicates.instantiate(self, &free_substs).predicates;
let predicates = self.lookup_predicates(def_id);
let predicates = predicates.instantiate(self, free_substs).predicates;
elaborate_predicates(self, predicates)
.any(|predicate| {
match predicate {
@ -214,7 +209,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
// Any method that has a `Self : Sized` requisite is otherwise
// exempt from the regulations.
if self.generics_require_sized_self(&method.generics, &method.predicates) {
if self.generics_require_sized_self(method.def_id) {
return None;
}
@ -231,7 +226,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
-> bool
{
// Any method that has a `Self : Sized` requisite can't be called.
if self.generics_require_sized_self(&method.generics, &method.predicates) {
if self.generics_require_sized_self(method.def_id) {
return false;
}

View File

@ -42,6 +42,7 @@ use traits;
use ty::fast_reject;
use ty::relate::TypeRelation;
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
use std::cell::RefCell;
use std::fmt;
@ -1935,7 +1936,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// for `PhantomData<T>`, we pass `T`
ty::TyStruct(def, substs) if def.is_phantom_data() => {
substs.types.get_slice(TypeSpace).to_vec()
substs.types.as_full_slice().to_vec()
}
ty::TyStruct(def, substs) | ty::TyEnum(def, substs) => {
@ -2584,17 +2585,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
} else {
return Err(Unimplemented);
};
let mut ty_params = vec![];
let mut ty_params = BitVector::new(substs_a.types.len(TypeSpace));
let mut found = false;
for ty in field.walk() {
if let ty::TyParam(p) = ty.sty {
assert!(p.space == TypeSpace);
let idx = p.idx as usize;
if !ty_params.contains(&idx) {
ty_params.push(idx);
}
ty_params.insert(p.idx as usize);
found = true;
}
}
if ty_params.is_empty() {
if !found {
return Err(Unimplemented);
}
@ -2602,12 +2602,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// TyError and ensure they do not affect any other fields.
// This could be checked after type collection for any struct
// with a potentially unsized trailing field.
let mut new_substs = substs_a.clone();
for &i in &ty_params {
new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err;
}
let types = substs_a.types.map_enumerated(|(_, i, ty)| {
if ty_params.contains(i) {
tcx.types.err
} else {
ty
}
});
let substs = Substs::new(tcx, types, substs_a.regions.clone());
for &ty in fields.split_last().unwrap().1 {
if ty.subst(tcx, &new_substs).references_error() {
if ty.subst(tcx, substs).references_error() {
return Err(Unimplemented);
}
}
@ -2618,11 +2622,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// Check that the source structure with the target's
// type parameters is a subtype of the target.
for &i in &ty_params {
let param_b = *substs_b.types.get(TypeSpace, i);
new_substs.types.get_mut_slice(TypeSpace)[i] = param_b;
}
let new_struct = tcx.mk_struct(def, tcx.mk_substs(new_substs));
let types = substs_a.types.map_enumerated(|(_, i, ty)| {
if ty_params.contains(i) {
*substs_b.types.get(TypeSpace, i)
} else {
ty
}
});
let substs = Substs::new(tcx, types, substs_a.regions.clone());
let new_struct = tcx.mk_struct(def, substs);
let origin = TypeOrigin::Misc(obligation.cause.span);
let InferOk { obligations, .. } =
self.infcx.sub_types(false, origin, new_struct, target)
@ -2691,12 +2699,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
snapshot);
let skol_obligation_trait_ref = skol_obligation.trait_ref;
let impl_substs = util::fresh_type_vars_for_impl(self.infcx,
obligation.cause.span,
impl_def_id);
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span,
impl_def_id);
let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
&impl_substs);
impl_substs);
let impl_trait_ref =
project::normalize_with_depth(self,

View File

@ -18,7 +18,7 @@
// fits together with the rest of the trait machinery.
use super::{SelectionContext, FulfillmentContext};
use super::util::{fresh_type_vars_for_impl, impl_trait_ref_and_oblig};
use super::util::impl_trait_ref_and_oblig;
use rustc_data_structures::fnv::FnvHashMap;
use hir::def_id::DefId;
@ -101,7 +101,7 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
};
// directly inherent the method generics, since those do not vary across impls
infcx.tcx.mk_substs(target_substs.with_method_from_subst(source_substs))
source_substs.rebase_onto(infcx.tcx, source_impl, target_substs)
}
/// Is impl1 a specialization of impl2?
@ -141,11 +141,8 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
// create a parameter environment corresponding to a (skolemized) instantiation of impl1
let scheme = tcx.lookup_item_type(impl1_def_id);
let predicates = tcx.lookup_predicates(impl1_def_id);
let mut penv = tcx.construct_parameter_environment(DUMMY_SP,
&scheme.generics,
&predicates,
impl1_def_id,
region::DUMMY_CODE_EXTENT);
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id)
.unwrap()
@ -188,10 +185,10 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
target_impl: DefId)
-> Result<&'tcx Substs<'tcx>, ()> {
let selcx = &mut SelectionContext::new(&infcx);
let target_substs = fresh_type_vars_for_impl(&infcx, DUMMY_SP, target_impl);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx,
target_impl,
&target_substs);
target_substs);
// do the impls unify? If not, no specialization.
if let Err(_) = infcx.eq_trait_refs(true,

View File

@ -122,19 +122,18 @@ impl<'a, 'gcx, 'tcx> Children {
if le == ge {
// overlap, but no specialization; error out
let trait_ref = impl_header.trait_ref.unwrap();
let self_ty = trait_ref.self_ty();
Err(OverlapError {
with_impl: possible_sibling,
trait_desc: trait_ref.to_string(),
self_desc: trait_ref.substs.self_ty().and_then(|ty| {
// only report the Self type if it has at least
// some outer concrete shell; otherwise, it's
// not adding much information.
if ty.has_concrete_skeleton() {
Some(ty.to_string())
} else {
None
}
})
// only report the Self type if it has at least
// some outer concrete shell; otherwise, it's
// not adding much information.
self_desc: if self_ty.has_concrete_skeleton() {
Some(self_ty.to_string())
} else {
None
}
})
} else {
Ok((le, ge))

View File

@ -9,10 +9,8 @@
// except according to those terms.
use hir::def_id::DefId;
use infer::InferCtxt;
use ty::subst::{Subst, Substs};
use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
use syntax_pos::Span;
use util::common::ErrorReported;
use util::nodemap::FnvHashSet;
@ -349,19 +347,6 @@ pub fn impl_trait_ref_and_oblig<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a,
(impl_trait_ref, impl_obligations)
}
// determine the `self` type, using fresh variables for all variables
// declared on the impl declaration e.g., `impl<A,B> for Box<[(A,B)]>`
// would return ($0, $1) where $0 and $1 are freshly instantiated type
// variables.
pub fn fresh_type_vars_for_impl<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
span: Span,
impl_def_id: DefId)
-> &'tcx Substs<'tcx>
{
let impl_generics = infcx.tcx.lookup_item_type(impl_def_id).generics;
infcx.fresh_substs_for_generics(span, &impl_generics)
}
/// See `super::obligations_for_generics`
pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
recursion_depth: usize,
@ -401,7 +386,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
Ok(def_id) => {
Ok(ty::TraitRef {
def_id: def_id,
substs: self.mk_substs(Substs::empty().with_self_ty(param_ty))
substs: Substs::new_trait(self, vec![], vec![], param_ty)
})
}
Err(e) => {
@ -421,7 +406,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
{
let trait_ref = ty::TraitRef {
def_id: trait_def_id,
substs: self.mk_substs(Substs::new_trait(ty_params, vec![], param_ty))
substs: Substs::new_trait(self, ty_params, vec![], param_ty)
};
predicate_for_trait_ref(cause, trait_ref, recursion_depth)
}
@ -509,10 +494,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
TupleArgumentsFlag::No => sig.0.inputs[0],
TupleArgumentsFlag::Yes => self.mk_tup(sig.0.inputs.to_vec()),
};
let trait_substs = Substs::new_trait(vec![arguments_tuple], vec![], self_ty);
let trait_ref = ty::TraitRef {
def_id: fn_trait_def_id,
substs: self.mk_substs(trait_substs),
substs: Substs::new_trait(self, vec![arguments_tuple], vec![], self_ty),
};
ty::Binder((trait_ref, sig.0.output))
}

View File

@ -63,6 +63,7 @@ pub struct CtxtArenas<'tcx> {
layout: TypedArena<Layout>,
// references
generics: TypedArena<ty::Generics<'tcx>>,
trait_defs: TypedArena<ty::TraitDef<'tcx>>,
adt_defs: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
}
@ -78,6 +79,7 @@ impl<'tcx> CtxtArenas<'tcx> {
stability: TypedArena::new(),
layout: TypedArena::new(),
generics: TypedArena::new(),
trait_defs: TypedArena::new(),
adt_defs: TypedArena::new()
}
@ -341,7 +343,8 @@ pub struct GlobalCtxt<'tcx> {
pub adt_defs: RefCell<DepTrackingMap<maps::AdtDefs<'tcx>>>,
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
/// associated predicates.
/// associated generics and predicates.
pub generics: RefCell<DepTrackingMap<maps::Generics<'tcx>>>,
pub predicates: RefCell<DepTrackingMap<maps::Predicates<'tcx>>>,
/// Maps from the def-id of a trait to the list of
@ -583,13 +586,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.tables.borrow_mut().node_types.insert(id, ty);
}
pub fn alloc_generics(self, generics: ty::Generics<'gcx>)
-> &'gcx ty::Generics<'gcx> {
self.global_interners.arenas.generics.alloc(generics)
}
pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
-> &'gcx ty::TraitDef<'gcx> {
let did = def.trait_ref.def_id;
let interned = self.global_interners.arenas.trait_defs.alloc(def);
let interned = self.alloc_trait_def(def);
if let Some(prev) = self.trait_defs.borrow_mut().insert(did, interned) {
bug!("Tried to overwrite interned TraitDef: {:?}", prev)
}
self.generics.borrow_mut().insert(did, interned.generics);
interned
}
@ -711,6 +720,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
impl_trait_refs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
trait_defs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
adt_defs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
generics: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
fulfilled_predicates: RefCell::new(fulfilled_predicates),

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ty::subst;
use ty::subst::{self, Substs};
use ty::{self, Ty, TypeFlags, TypeFoldable};
pub struct FlagComputation {
@ -207,7 +207,7 @@ impl FlagComputation {
self.add_substs(projection_ty.trait_ref.substs);
}
fn add_substs(&mut self, substs: &subst::Substs) {
fn add_substs(&mut self, substs: &Substs) {
self.add_tys(substs.types.as_full_slice());
for &r in substs.regions.as_full_slice() {
self.add_region(r);

View File

@ -40,7 +40,7 @@
//! and does not need to visit anything else.
use middle::region;
use ty::subst;
use ty::subst::Substs;
use ty::adjustment;
use ty::{self, Binder, Ty, TyCtxt, TypeFlags};
@ -145,8 +145,8 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized {
}
fn fold_substs(&mut self,
substs: &'tcx subst::Substs<'tcx>)
-> &'tcx subst::Substs<'tcx> {
substs: &'tcx Substs<'tcx>)
-> &'tcx Substs<'tcx> {
substs.super_fold_with(self)
}

View File

@ -10,7 +10,7 @@
use dep_graph::{DepNode, DepTrackingMapConfig};
use hir::def_id::DefId;
use ty;
use ty::{self, Ty};
use std::marker::PhantomData;
use std::rc::Rc;
use syntax::{attr, ast};
@ -30,7 +30,8 @@ macro_rules! dep_map_ty {
}
dep_map_ty! { ImplOrTraitItems: ImplOrTraitItems(DefId) -> ty::ImplOrTraitItem<'tcx> }
dep_map_ty! { Tcache: ItemSignature(DefId) -> ty::TypeScheme<'tcx> }
dep_map_ty! { Tcache: ItemSignature(DefId) -> Ty<'tcx> }
dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics<'tcx> }
dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
dep_map_ty! { TraitItemDefIds: TraitItemDefIds(DefId) -> Rc<Vec<ty::ImplOrTraitItemId>> }

View File

@ -173,15 +173,14 @@ impl<'a, 'gcx, 'tcx> ImplHeader<'tcx> {
-> ImplHeader<'tcx>
{
let tcx = selcx.tcx();
let impl_generics = tcx.lookup_item_type(impl_def_id).generics;
let impl_substs = selcx.infcx().fresh_substs_for_generics(DUMMY_SP, &impl_generics);
let impl_substs = selcx.infcx().fresh_substs_for_item(DUMMY_SP, impl_def_id);
let header = ImplHeader {
impl_def_id: impl_def_id,
self_ty: tcx.lookup_item_type(impl_def_id).ty,
trait_ref: tcx.impl_trait_ref(impl_def_id),
predicates: tcx.lookup_predicates(impl_def_id).predicates
}.subst(tcx, &impl_substs);
}.subst(tcx, impl_substs);
let traits::Normalized { value: mut header, obligations } =
traits::normalize(selcx, traits::ObligationCause::dummy(), &header);
@ -348,7 +347,7 @@ impl Visibility {
#[derive(Clone, Debug)]
pub struct Method<'tcx> {
pub name: Name,
pub generics: Generics<'tcx>,
pub generics: &'tcx Generics<'tcx>,
pub predicates: GenericPredicates<'tcx>,
pub fty: &'tcx BareFnTy<'tcx>,
pub explicit_self: ExplicitSelfCategory,
@ -360,7 +359,7 @@ pub struct Method<'tcx> {
impl<'tcx> Method<'tcx> {
pub fn new(name: Name,
generics: ty::Generics<'tcx>,
generics: &'tcx ty::Generics<'tcx>,
predicates: GenericPredicates<'tcx>,
fty: &'tcx BareFnTy<'tcx>,
explicit_self: ExplicitSelfCategory,
@ -453,7 +452,7 @@ pub struct MethodCallee<'tcx> {
/// Impl method ID, for inherent methods, or trait method ID, otherwise.
pub def_id: DefId,
pub ty: Ty<'tcx>,
pub substs: &'tcx subst::Substs<'tcx>
pub substs: &'tcx Substs<'tcx>
}
/// With method calls, we store some extra information in
@ -760,6 +759,7 @@ impl RegionParameterDef {
pub struct Generics<'tcx> {
pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
pub regions: VecPerParamSpace<RegionParameterDef>,
pub has_self: bool,
}
impl<'tcx> Generics<'tcx> {
@ -767,6 +767,7 @@ impl<'tcx> Generics<'tcx> {
Generics {
types: VecPerParamSpace::empty(),
regions: VecPerParamSpace::empty(),
has_self: false,
}
}
@ -1224,7 +1225,7 @@ impl<'tcx> TraitRef<'tcx> {
}
pub fn self_ty(&self) -> Ty<'tcx> {
self.substs.self_ty().unwrap()
*self.substs.types.get(subst::SelfSpace, 0)
}
pub fn input_types(&self) -> &[Ty<'tcx>] {
@ -1298,23 +1299,17 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
// so for now just grab environment for the impl
let impl_id = tcx.map.get_parent(id);
let impl_def_id = tcx.map.local_def_id(impl_id);
let scheme = tcx.lookup_item_type(impl_def_id);
let predicates = tcx.lookup_predicates(impl_def_id);
tcx.construct_parameter_environment(impl_item.span,
&scheme.generics,
&predicates,
impl_def_id,
tcx.region_maps.item_extent(id))
}
hir::ImplItemKind::Method(_, ref body) => {
let method_def_id = tcx.map.local_def_id(id);
match tcx.impl_or_trait_item(method_def_id) {
MethodTraitItem(ref method_ty) => {
let method_generics = &method_ty.generics;
let method_bounds = &method_ty.predicates;
tcx.construct_parameter_environment(
impl_item.span,
method_generics,
method_bounds,
method_ty.def_id,
tcx.region_maps.call_site_extent(id, body.id))
}
_ => {
@ -1332,11 +1327,8 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
// so for now just grab environment for the trait
let trait_id = tcx.map.get_parent(id);
let trait_def_id = tcx.map.local_def_id(trait_id);
let trait_def = tcx.lookup_trait_def(trait_def_id);
let predicates = tcx.lookup_predicates(trait_def_id);
tcx.construct_parameter_environment(trait_item.span,
&trait_def.generics,
&predicates,
trait_def_id,
tcx.region_maps.item_extent(id))
}
hir::MethodTraitItem(_, ref body) => {
@ -1346,8 +1338,6 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
let method_def_id = tcx.map.local_def_id(id);
match tcx.impl_or_trait_item(method_def_id) {
MethodTraitItem(ref method_ty) => {
let method_generics = &method_ty.generics;
let method_bounds = &method_ty.predicates;
let extent = if let Some(ref body) = *body {
// default impl: use call_site extent as free_id_outlive bound.
tcx.region_maps.call_site_extent(id, body.id)
@ -1357,8 +1347,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
};
tcx.construct_parameter_environment(
trait_item.span,
method_generics,
method_bounds,
method_ty.def_id,
extent)
}
_ => {
@ -1375,13 +1364,10 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
hir::ItemFn(_, _, _, _, _, ref body) => {
// We assume this is a function.
let fn_def_id = tcx.map.local_def_id(id);
let fn_scheme = tcx.lookup_item_type(fn_def_id);
let fn_predicates = tcx.lookup_predicates(fn_def_id);
tcx.construct_parameter_environment(
item.span,
&fn_scheme.generics,
&fn_predicates,
fn_def_id,
tcx.region_maps.call_site_extent(id, body.id))
}
hir::ItemEnum(..) |
@ -1391,20 +1377,14 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
hir::ItemConst(..) |
hir::ItemStatic(..) => {
let def_id = tcx.map.local_def_id(id);
let scheme = tcx.lookup_item_type(def_id);
let predicates = tcx.lookup_predicates(def_id);
tcx.construct_parameter_environment(item.span,
&scheme.generics,
&predicates,
def_id,
tcx.region_maps.item_extent(id))
}
hir::ItemTrait(..) => {
let def_id = tcx.map.local_def_id(id);
let trait_def = tcx.lookup_trait_def(def_id);
let predicates = tcx.lookup_predicates(def_id);
tcx.construct_parameter_environment(item.span,
&trait_def.generics,
&predicates,
def_id,
tcx.region_maps.item_extent(id))
}
_ => {
@ -1425,11 +1405,8 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
}
Some(ast_map::NodeForeignItem(item)) => {
let def_id = tcx.map.local_def_id(id);
let scheme = tcx.lookup_item_type(def_id);
let predicates = tcx.lookup_predicates(def_id);
tcx.construct_parameter_environment(item.span,
&scheme.generics,
&predicates,
def_id,
ROOT_CODE_EXTENT)
}
_ => {
@ -1462,7 +1439,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
/// `lookup_predicates`.
#[derive(Clone, Debug)]
pub struct TypeScheme<'tcx> {
pub generics: Generics<'tcx>,
pub generics: &'tcx Generics<'tcx>,
pub ty: Ty<'tcx>,
}
@ -1917,9 +1894,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
};
let sized_predicate = Binder(TraitRef {
def_id: sized_trait,
substs: tcx.mk_substs(Substs::new_trait(
vec![], vec![], ty
))
substs: Substs::new_trait(tcx, vec![], vec![], ty)
}).to_predicate();
let predicates = tcx.lookup_predicates(self.did).predicates;
if predicates.into_iter().any(|p| p == sized_predicate) {
@ -2170,7 +2145,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: self.global_tcx().mk_substs(Substs::empty())
substs: Substs::empty(self.global_tcx())
},
Some(ts) => ts.clone(),
}
@ -2508,27 +2483,36 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
// Register a given item type
pub fn register_item_type(self, did: DefId, ty: TypeScheme<'gcx>) {
self.tcache.borrow_mut().insert(did, ty);
pub fn register_item_type(self, did: DefId, scheme: TypeScheme<'gcx>) {
self.tcache.borrow_mut().insert(did, scheme.ty);
self.generics.borrow_mut().insert(did, scheme.generics);
}
// If the given item is in an external crate, looks up its type and adds it to
// the type cache. Returns the type parameters and type.
pub fn lookup_item_type(self, did: DefId) -> TypeScheme<'gcx> {
lookup_locally_or_in_crate_store(
let ty = lookup_locally_or_in_crate_store(
"tcache", did, &self.tcache,
|| self.sess.cstore.item_type(self.global_tcx(), did))
|| self.sess.cstore.item_type(self.global_tcx(), did));
TypeScheme {
ty: ty,
generics: self.lookup_generics(did)
}
}
pub fn opt_lookup_item_type(self, did: DefId) -> Option<TypeScheme<'gcx>> {
if let Some(scheme) = self.tcache.borrow_mut().get(&did) {
return Some(scheme.clone());
if did.krate != LOCAL_CRATE {
return Some(self.lookup_item_type(did));
}
if did.krate == LOCAL_CRATE {
None
if let Some(ty) = self.tcache.borrow().get(&did).cloned() {
Some(TypeScheme {
ty: ty,
generics: self.lookup_generics(did)
})
} else {
Some(self.sess.cstore.item_type(self.global_tcx(), did))
None
}
}
@ -2557,6 +2541,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.lookup_adt_def_master(did)
}
/// Given the did of an item, returns its generics.
pub fn lookup_generics(self, did: DefId) -> &'gcx Generics<'gcx> {
lookup_locally_or_in_crate_store(
"generics", did, &self.generics,
|| self.sess.cstore.item_generics(self.global_tcx(), did))
}
/// Given the did of an item, returns its full set of predicates.
pub fn lookup_predicates(self, did: DefId) -> GenericPredicates<'gcx> {
lookup_locally_or_in_crate_store(
@ -2812,18 +2803,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}
/// If the given def ID describes an item belonging to a trait (either a
/// default method or an implementation of a trait method), return the ID of
/// the trait that the method belongs to. Otherwise, return `None`.
/// If the given def ID describes an item belonging to a trait,
/// return the ID of the trait that the trait item belongs to.
/// Otherwise, return `None`.
pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
if def_id.krate != LOCAL_CRATE {
return self.sess.cstore.trait_of_item(self.global_tcx(), def_id);
return self.sess.cstore.trait_of_item(def_id);
}
match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
match self.impl_or_trait_items.borrow().get(&def_id) {
Some(impl_or_trait_item) => {
match impl_or_trait_item.container() {
TraitContainer(def_id) => Some(def_id),
ImplContainer(def_id) => self.trait_id_of_impl(def_id),
ImplContainer(_) => None
}
}
None => None
@ -2837,18 +2828,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// the same).
/// Otherwise, return `None`.
pub fn trait_item_of_item(self, def_id: DefId) -> Option<ImplOrTraitItemId> {
let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) {
let impl_or_trait_item = match self.impl_or_trait_items.borrow().get(&def_id) {
Some(m) => m.clone(),
None => return None,
};
let name = impl_item.name();
match self.trait_of_item(def_id) {
Some(trait_did) => {
self.trait_items(trait_did).iter()
.find(|item| item.name() == name)
.map(|item| item.id())
match impl_or_trait_item.container() {
TraitContainer(_) => Some(impl_or_trait_item.id()),
ImplContainer(def_id) => {
self.trait_id_of_impl(def_id).and_then(|trait_did| {
let name = impl_or_trait_item.name();
self.trait_items(trait_did).iter()
.find(|item| item.name() == name)
.map(|item| item.id())
})
}
None => None
}
}
@ -2860,7 +2853,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: self.mk_substs(Substs::empty()),
free_substs: Substs::empty(self),
caller_bounds: Vec::new(),
implicit_region_bound: ty::ReEmpty,
free_id_outlive: free_id_outlive
@ -2872,28 +2865,21 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// In general, this means converting from bound parameters to
/// free parameters. Since we currently represent bound/free type
/// parameters in the same way, this only has an effect on regions.
pub fn construct_free_substs(self, generics: &Generics<'gcx>,
free_id_outlive: CodeExtent) -> Substs<'gcx> {
// map T => T
let types = generics.types.map(|def| {
debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
def);
pub fn construct_free_substs(self, def_id: DefId,
free_id_outlive: CodeExtent)
-> &'gcx Substs<'gcx> {
let substs = Substs::for_item(self.global_tcx(), def_id, |def, _| {
// map bound 'a => free 'a
ReFree(FreeRegion { scope: free_id_outlive,
bound_region: def.to_bound_region() })
}, |def, _| {
// map T => T
self.global_tcx().mk_param_from_def(def)
});
// map bound 'a => free 'a
let regions = generics.regions.map(|def| {
let region =
ReFree(FreeRegion { scope: free_id_outlive,
bound_region: def.to_bound_region() });
debug!("push_region_params {:?}", region);
region
});
Substs {
types: types,
regions: regions,
}
debug!("construct_parameter_environment: {:?}", substs);
substs
}
/// See `ParameterEnvironment` struct def'n for details.
@ -2901,8 +2887,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// for the `free_id_outlive` parameter. (But note that that is not always quite right.)
pub fn construct_parameter_environment(self,
span: Span,
generics: &ty::Generics<'gcx>,
generic_predicates: &ty::GenericPredicates<'gcx>,
def_id: DefId,
free_id_outlive: CodeExtent)
-> ParameterEnvironment<'gcx>
{
@ -2910,14 +2895,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// Construct the free substs.
//
let free_substs = self.construct_free_substs(generics, free_id_outlive);
let free_substs = self.construct_free_substs(def_id, free_id_outlive);
//
// Compute the bounds on Self and the type parameters.
//
let tcx = self.global_tcx();
let bounds = generic_predicates.instantiate(tcx, &free_substs);
let generic_predicates = tcx.lookup_predicates(def_id);
let bounds = generic_predicates.instantiate(tcx, free_substs);
let bounds = tcx.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
let predicates = bounds.predicates;
@ -2935,7 +2921,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
//
let unnormalized_env = ty::ParameterEnvironment {
free_substs: tcx.mk_substs(free_substs),
free_substs: free_substs,
implicit_region_bound: ty::ReScope(free_id_outlive),
caller_bounds: predicates,
free_id_outlive: free_id_outlive,

View File

@ -14,7 +14,7 @@
//! type equality, etc.
use hir::def_id::DefId;
use ty::subst::{ParamSpace, Substs};
use ty::subst::Substs;
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::error::{ExpectedFound, TypeError};
use std::rc::Rc;
@ -145,82 +145,44 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
-> RelateResult<'tcx, &'tcx Substs<'tcx>>
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
let mut substs = Substs::empty();
let tcx = relation.tcx();
let mut result = Ok(());
for &space in &ParamSpace::all() {
let a_tps = a_subst.types.get_slice(space);
let b_tps = b_subst.types.get_slice(space);
let t_variances = variances.map(|v| v.types.get_slice(space));
let tps = relate_type_params(relation, t_variances, a_tps, b_tps)?;
substs.types.replace(space, tps);
}
let types = a_subst.types.map_enumerated(|(space, i, a_ty)| {
if result.is_err() { return tcx.types.err; }
for &space in &ParamSpace::all() {
let a_regions = a_subst.regions.get_slice(space);
let b_regions = b_subst.regions.get_slice(space);
let r_variances = variances.map(|v| v.regions.get_slice(space));
let regions = relate_region_params(relation,
r_variances,
a_regions,
b_regions)?;
substs.regions.replace(space, regions);
}
let b_ty = b_subst.types.get(space, i);
let variance = variances.map_or(ty::Invariant, |v| {
*v.types.get(space, i)
});
match relation.relate_with_variance(variance, a_ty, b_ty) {
Ok(ty) => ty,
Err(e) => {
result = Err(e);
tcx.types.err
}
}
});
result?;
Ok(relation.tcx().mk_substs(substs))
}
let regions = a_subst.regions.map_enumerated(|(space, i, a_r)| {
if result.is_err() { return ty::ReStatic; }
fn relate_type_params<'a, 'gcx, 'tcx, R>(relation: &mut R,
variances: Option<&[ty::Variance]>,
a_tys: &[Ty<'tcx>],
b_tys: &[Ty<'tcx>])
-> RelateResult<'tcx, Vec<Ty<'tcx>>>
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
if a_tys.len() != b_tys.len() {
return Err(TypeError::TyParamSize(expected_found(relation,
&a_tys.len(),
&b_tys.len())));
}
let b_r = b_subst.regions.get(space, i);
let variance = variances.map_or(ty::Invariant, |v| {
*v.regions.get(space, i)
});
match relation.relate_with_variance(variance, a_r, b_r) {
Ok(r) => r,
Err(e) => {
result = Err(e);
ty::ReStatic
}
}
});
result?;
(0 .. a_tys.len())
.map(|i| {
let a_ty = a_tys[i];
let b_ty = b_tys[i];
let v = variances.map_or(ty::Invariant, |v| v[i]);
relation.relate_with_variance(v, &a_ty, &b_ty)
})
.collect()
}
fn relate_region_params<'a, 'gcx, 'tcx, R>(relation: &mut R,
variances: Option<&[ty::Variance]>,
a_rs: &[ty::Region],
b_rs: &[ty::Region])
-> RelateResult<'tcx, Vec<ty::Region>>
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
{
let num_region_params = a_rs.len();
debug!("relate_region_params(a_rs={:?}, \
b_rs={:?}, variances={:?})",
a_rs,
b_rs,
variances);
assert_eq!(num_region_params,
variances.map_or(num_region_params,
|v| v.len()));
assert_eq!(num_region_params, b_rs.len());
(0..a_rs.len())
.map(|i| {
let a_r = a_rs[i];
let b_r = b_rs[i];
let variance = variances.map_or(ty::Invariant, |v| v[i]);
relation.relate_with_variance(variance, &a_r, &b_r)
})
.collect()
Ok(Substs::new(tcx, types, regions))
}
impl<'tcx> Relate<'tcx> for &'tcx ty::BareFnTy<'tcx> {

View File

@ -9,7 +9,7 @@
// except according to those terms.
use infer::type_variable;
use ty::subst::{self, VecPerParamSpace};
use ty::subst::{Substs, VecPerParamSpace};
use ty::{self, Lift, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@ -702,13 +702,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx subst::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 {
let substs = subst::Substs {
regions: self.regions.fold_with(folder),
types: self.types.fold_with(folder)
};
folder.tcx().mk_substs(substs)
let types = self.types.fold_with(folder);
let regions = self.regions.fold_with(folder);
Substs::new(folder.tcx(), types, regions)
}
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
@ -839,6 +837,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> {
ty::Generics {
types: self.types.fold_with(folder),
regions: self.regions.fold_with(folder),
has_self: self.has_self
}
}
@ -1018,19 +1017,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::TypeScheme<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::TypeScheme {
generics: self.generics.fold_with(folder),
ty: self.ty.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.generics.visit_with(visitor) || self.ty.visit_with(visitor)
}
}
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::error::ExpectedFound {

View File

@ -359,18 +359,7 @@ pub struct ExistentialTraitRef<'tcx> {
pub substs: &'tcx Substs<'tcx>,
}
impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> {
pub fn erase_self_ty(tcx: TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: ty::TraitRef<'tcx>)
-> ty::ExistentialTraitRef<'tcx> {
let mut substs = trait_ref.substs.clone();
substs.types.pop(subst::SelfSpace);
ty::ExistentialTraitRef {
def_id: trait_ref.def_id,
substs: tcx.mk_substs(substs)
}
}
impl<'tcx> ExistentialTraitRef<'tcx> {
pub fn input_types(&self) -> &[Ty<'tcx>] {
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
@ -382,7 +371,7 @@ impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> {
pub type PolyExistentialTraitRef<'tcx> = Binder<ExistentialTraitRef<'tcx>>;
impl<'a, 'gcx, 'tcx> PolyExistentialTraitRef<'tcx> {
impl<'tcx> PolyExistentialTraitRef<'tcx> {
pub fn def_id(&self) -> DefId {
self.0.def_id
}
@ -391,23 +380,6 @@ impl<'a, 'gcx, 'tcx> PolyExistentialTraitRef<'tcx> {
// FIXME(#20664) every use of this fn is probably a bug, it should yield Binder<>
self.0.input_types()
}
/// Object types don't have a self-type specified. Therefore, when
/// we convert the principal trait-ref into a normal trait-ref,
/// you must give *some* self-type. A common choice is `mk_err()`
/// or some skolemized type.
pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
self_ty: Ty<'tcx>)
-> ty::PolyTraitRef<'tcx>
{
// otherwise the escaping regions would be captured by the binder
assert!(!self_ty.has_escaping_regions());
self.map_bound(|trait_ref| TraitRef {
def_id: trait_ref.def_id,
substs: tcx.mk_substs(trait_ref.substs.with_self_ty(self_ty)),
})
}
}
/// Binder is a binder for higher-ranked lifetimes. It is part of the

View File

@ -34,43 +34,45 @@ pub struct Substs<'tcx> {
}
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
pub fn new(t: VecPerParamSpace<Ty<'tcx>>,
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
t: VecPerParamSpace<Ty<'tcx>>,
r: VecPerParamSpace<ty::Region>)
-> Substs<'tcx>
-> &'tcx Substs<'tcx>
{
Substs { types: t, regions: r }
tcx.mk_substs(Substs { types: t, regions: r })
}
pub fn new_fn(t: Vec<Ty<'tcx>>,
pub fn new_fn(tcx: TyCtxt<'a, 'gcx, 'tcx>,
t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>)
-> Substs<'tcx>
-> &'tcx Substs<'tcx>
{
Substs::new(VecPerParamSpace::new(vec![], vec![], t),
Substs::new(tcx, VecPerParamSpace::new(vec![], vec![], t),
VecPerParamSpace::new(vec![], vec![], r))
}
pub fn new_type(t: Vec<Ty<'tcx>>,
pub fn new_type(tcx: TyCtxt<'a, 'gcx, 'tcx>,
t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>)
-> Substs<'tcx>
-> &'tcx Substs<'tcx>
{
Substs::new(VecPerParamSpace::new(vec![], t, vec![]),
Substs::new(tcx, VecPerParamSpace::new(vec![], t, vec![]),
VecPerParamSpace::new(vec![], r, vec![]))
}
pub fn new_trait(t: Vec<Ty<'tcx>>,
pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>,
t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>,
s: Ty<'tcx>)
-> Substs<'tcx>
-> &'tcx Substs<'tcx>
{
Substs::new(VecPerParamSpace::new(vec![s], t, vec![]),
Substs::new(tcx, VecPerParamSpace::new(vec![s], t, vec![]),
VecPerParamSpace::new(vec![], r, vec![]))
}
pub fn empty() -> Substs<'tcx> {
Substs {
types: VecPerParamSpace::empty(),
regions: VecPerParamSpace::empty(),
}
pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> {
Substs::new(tcx, VecPerParamSpace::empty(),
VecPerParamSpace::empty())
}
/// Creates a Substs for generic parameter definitions,
@ -78,26 +80,57 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
/// The closures get to observe the Substs as they're
/// being built, which can be used to correctly
/// substitute defaults of type parameters.
pub fn from_generics<FR, FT>(generics: &ty::Generics<'tcx>,
mut mk_region: FR,
mut mk_type: FT)
-> Substs<'tcx>
pub fn for_item<FR, FT>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
def_id: DefId,
mut mk_region: FR,
mut mk_type: FT)
-> &'tcx Substs<'tcx>
where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
let mut substs = Substs::empty();
for &space in &ParamSpace::all() {
for def in generics.regions.get_slice(space) {
let region = mk_region(def, &substs);
assert_eq!(substs.regions.len(def.space), def.index as usize);
substs.regions.push(def.space, region);
let defs = tcx.lookup_generics(def_id);
let mut substs = Substs {
types: VecPerParamSpace {
self_limit: 0,
type_limit: 0,
content: Vec::with_capacity(defs.types.content.len())
},
regions: VecPerParamSpace {
self_limit: 0,
type_limit: 0,
content: Vec::with_capacity(defs.regions.content.len())
}
for def in generics.types.get_slice(space) {
};
for &space in &ParamSpace::all() {
for def in defs.regions.get_slice(space) {
assert_eq!(def.space, space);
assert!(space != SelfSpace);
let region = mk_region(def, &substs);
substs.regions.content.push(region);
if space == TypeSpace {
substs.regions.type_limit += 1;
}
}
for def in defs.types.get_slice(space) {
assert_eq!(def.space, space);
let ty = mk_type(def, &substs);
assert_eq!(substs.types.len(def.space), def.index as usize);
substs.types.push(def.space, ty);
substs.types.content.push(ty);
if space == SelfSpace {
substs.types.self_limit += 1;
}
if space <= TypeSpace {
substs.types.type_limit += 1;
}
}
}
substs
Substs::new(tcx, substs.types, substs.regions)
}
pub fn is_noop(&self) -> bool {
@ -112,66 +145,32 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
*self.regions.get(def.space, def.index as usize)
}
pub fn self_ty(&self) -> Option<Ty<'tcx>> {
self.types.get_self().cloned()
}
/// Transform from substitutions for a child of `source_ancestor`
/// (e.g. a trait or impl) to substitutions for the same child
/// in a different item, with `target_substs` as the base for
/// the target impl/trait, with the source child-specific
/// parameters (e.g. method parameters) on top of that base.
pub fn rebase_onto(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
source_ancestor: DefId,
target_substs: &Substs<'tcx>)
-> &'tcx Substs<'tcx> {
let defs = tcx.lookup_generics(source_ancestor);
assert_eq!(self.types.len(SelfSpace), defs.types.len(SelfSpace));
assert_eq!(self.types.len(TypeSpace), defs.types.len(TypeSpace));
assert_eq!(target_substs.types.len(FnSpace), 0);
assert_eq!(defs.types.len(FnSpace), 0);
assert_eq!(self.regions.len(TypeSpace), defs.regions.len(TypeSpace));
assert_eq!(target_substs.regions.len(FnSpace), 0);
assert_eq!(defs.regions.len(FnSpace), 0);
pub fn with_self_ty(&self, self_ty: Ty<'tcx>) -> Substs<'tcx> {
assert!(self.self_ty().is_none());
let mut s = (*self).clone();
s.types.push(SelfSpace, self_ty);
s
}
pub fn erase_regions(self) -> Substs<'tcx> {
let Substs { types, regions } = self;
let regions = regions.map(|_| ty::ReErased);
Substs { types: types, regions: regions }
}
pub fn with_method(self,
m_types: Vec<Ty<'tcx>>,
m_regions: Vec<ty::Region>)
-> Substs<'tcx>
{
let Substs { types, regions } = self;
let types = types.with_slice(FnSpace, &m_types);
let regions = regions.with_slice(FnSpace, &m_regions);
Substs { types: types, regions: regions }
}
pub fn with_method_from(&self,
meth_substs: &Substs<'tcx>)
-> Substs<'tcx>
{
let Substs { types, regions } = self.clone();
let types = types.with_slice(FnSpace, meth_substs.types.get_slice(FnSpace));
let regions = regions.with_slice(FnSpace, meth_substs.regions.get_slice(FnSpace));
Substs { types: types, regions: regions }
}
pub fn with_method_from_subst(&self, other: &Substs<'tcx>) -> Substs<'tcx> {
let Substs { types, regions } = self.clone();
let types = types.with_slice(FnSpace, other.types.get_slice(FnSpace));
let regions = regions.with_slice(FnSpace, other.regions.get_slice(FnSpace));
Substs { types: types, regions: regions }
}
/// Creates a trait-ref out of this substs, ignoring the FnSpace substs
pub fn to_trait_ref(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_id: DefId)
-> ty::TraitRef<'tcx> {
let Substs { mut types, mut regions } = self.clone();
types.truncate(FnSpace, 0);
regions.truncate(FnSpace, 0);
ty::TraitRef {
def_id: trait_id,
substs: tcx.mk_substs(Substs { types: types, regions: regions })
}
let Substs { mut types, mut regions } = target_substs.clone();
types.content.extend(&self.types.as_full_slice()[defs.types.content.len()..]);
regions.content.extend(&self.regions.as_full_slice()[defs.regions.content.len()..]);
Substs::new(tcx, types, regions)
}
}
impl<'tcx> Encodable for Substs<'tcx> {
impl<'tcx> Encodable for &'tcx Substs<'tcx> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
cstore::tls::with_encoding_context(s, |ecx, rbml_w| {
ecx.encode_substs(rbml_w, self);
@ -180,19 +179,10 @@ impl<'tcx> Encodable for Substs<'tcx> {
}
}
impl<'tcx> Decodable for Substs<'tcx> {
fn decode<D: Decoder>(d: &mut D) -> Result<Substs<'tcx>, D::Error> {
cstore::tls::with_decoding_context(d, |dcx, rbml_r| {
Ok(dcx.decode_substs(rbml_r))
})
}
}
impl<'tcx> Decodable for &'tcx Substs<'tcx> {
fn decode<D: Decoder>(d: &mut D) -> Result<&'tcx Substs<'tcx>, D::Error> {
let substs = cstore::tls::with_decoding_context(d, |dcx, rbml_r| {
let substs = dcx.decode_substs(rbml_r);
dcx.tcx().mk_substs(substs)
dcx.decode_substs(rbml_r)
});
Ok(substs)
@ -307,70 +297,6 @@ impl<T> VecPerParamSpace<T> {
}
}
/// Appends `value` to the vector associated with `space`.
///
/// Unlike the `push` method in `Vec`, this should not be assumed
/// to be a cheap operation (even when amortized over many calls).
pub fn push(&mut self, space: ParamSpace, value: T) {
let (_, limit) = self.limits(space);
match space {
SelfSpace => { self.type_limit += 1; self.self_limit += 1; }
TypeSpace => { self.type_limit += 1; }
FnSpace => { }
}
self.content.insert(limit, value);
}
/// Appends `values` to the vector associated with `space`.
///
/// Unlike the `extend` method in `Vec`, this should not be assumed
/// to be a cheap operation (even when amortized over many calls).
pub fn extend<I:Iterator<Item=T>>(&mut self, space: ParamSpace, values: I) {
// This could be made more efficient, obviously.
for item in values {
self.push(space, item);
}
}
pub fn pop(&mut self, space: ParamSpace) -> Option<T> {
let (start, limit) = self.limits(space);
if start == limit {
None
} else {
match space {
SelfSpace => { self.type_limit -= 1; self.self_limit -= 1; }
TypeSpace => { self.type_limit -= 1; }
FnSpace => {}
}
if self.content.is_empty() {
None
} else {
Some(self.content.remove(limit - 1))
}
}
}
pub fn truncate(&mut self, space: ParamSpace, len: usize) {
// FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
while self.len(space) > len {
self.pop(space);
}
}
pub fn replace(&mut self, space: ParamSpace, elems: Vec<T>) {
// FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
self.truncate(space, 0);
for t in elems {
self.push(space, t);
}
}
pub fn get_self<'a>(&'a self) -> Option<&'a T> {
let v = self.get_slice(SelfSpace);
assert!(v.len() <= 1);
if v.is_empty() { None } else { Some(&v[0]) }
}
pub fn len(&self, space: ParamSpace) -> usize {
self.get_slice(space).len()
}
@ -384,19 +310,6 @@ impl<T> VecPerParamSpace<T> {
&self.content[start.. limit]
}
pub fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] {
let (start, limit) = self.limits(space);
&mut self.content[start.. limit]
}
pub fn opt_get<'a>(&'a self,
space: ParamSpace,
index: usize)
-> Option<&'a T> {
let v = self.get_slice(space);
if index < v.len() { Some(&v[index]) } else { None }
}
pub fn get<'a>(&'a self, space: ParamSpace, index: usize) -> &'a T {
&self.get_slice(space)[index]
}
@ -409,12 +322,6 @@ impl<T> VecPerParamSpace<T> {
&self.content
}
pub fn all_vecs<P>(&self, mut pred: P) -> bool where
P: FnMut(&[T]) -> bool,
{
ParamSpace::all().iter().all(|&space| { pred(self.get_slice(space)) })
}
pub fn all<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
self.as_full_slice().iter().all(pred)
}
@ -424,7 +331,7 @@ impl<T> VecPerParamSpace<T> {
}
pub fn is_empty(&self) -> bool {
self.all_vecs(|v| v.is_empty())
self.content.is_empty()
}
pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where P: FnMut(&T) -> U {
@ -442,18 +349,6 @@ impl<T> VecPerParamSpace<T> {
self.self_limit,
self.type_limit)
}
pub fn with_slice(mut self, space: ParamSpace, slice: &[T])
-> VecPerParamSpace<T>
where T: Clone
{
assert!(self.is_empty_in(space));
for t in slice {
self.push(space, t.clone());
}
self
}
}
#[derive(Clone)]
@ -581,7 +476,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
// the specialized routine `ty::replace_late_regions()`.
match r {
ty::ReEarlyBound(data) => {
match self.substs.regions.opt_get(data.space, data.index as usize) {
match self.substs.regions.get_slice(data.space).get(data.index as usize) {
Some(&r) => {
self.shift_region_through_binders(r)
}
@ -637,7 +532,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
// Look up the type in the substitutions. It really should be in there.
let opt_ty = self.substs.types.opt_get(p.space, p.idx as usize);
let opt_ty = self.substs.types.get_slice(p.space).get(p.idx as usize);
let ty = match opt_ty {
Some(t) => *t,
None => {
@ -718,3 +613,67 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
ty::fold::shift_region(region, self.region_binders_passed)
}
}
// Helper methods that modify substitutions.
impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
pub fn from_method(tcx: TyCtxt<'a, 'gcx, 'tcx>,
trait_id: DefId,
substs: &Substs<'tcx>)
-> ty::TraitRef<'tcx> {
let Substs { mut types, mut regions } = substs.clone();
let defs = tcx.lookup_generics(trait_id);
types.content.truncate(defs.types.type_limit);
regions.content.truncate(defs.regions.type_limit);
ty::TraitRef {
def_id: trait_id,
substs: Substs::new(tcx, types, regions)
}
}
}
impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
pub fn erase_self_ty(tcx: TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: ty::TraitRef<'tcx>)
-> ty::ExistentialTraitRef<'tcx> {
let Substs { mut types, regions } = trait_ref.substs.clone();
assert_eq!(types.self_limit, 1);
types.self_limit = 0;
types.type_limit -= 1;
types.content.remove(0);
ty::ExistentialTraitRef {
def_id: trait_ref.def_id,
substs: Substs::new(tcx, types, regions)
}
}
}
impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
/// Object types don't have a self-type specified. Therefore, when
/// we convert the principal trait-ref into a normal trait-ref,
/// you must give *some* self-type. A common choice is `mk_err()`
/// or some skolemized type.
pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
self_ty: Ty<'tcx>)
-> ty::PolyTraitRef<'tcx> {
// otherwise the escaping regions would be captured by the binder
assert!(!self_ty.has_escaping_regions());
self.map_bound(|trait_ref| {
let Substs { mut types, regions } = trait_ref.substs.clone();
assert_eq!(types.self_limit, 0);
types.self_limit = 1;
types.type_limit += 1;
types.content.insert(0, self_ty);
ty::TraitRef {
def_id: trait_ref.def_id,
substs: Substs::new(tcx, types, regions)
}
})
}
}

View File

@ -34,7 +34,7 @@ pub struct TraitDef<'tcx> {
/// `Eq`, there is a single bound `Self : Eq`). This is so that
/// default methods get to assume that the `Self` parameters
/// implements the trait.
pub generics: ty::Generics<'tcx>,
pub generics: &'tcx ty::Generics<'tcx>,
pub trait_ref: ty::TraitRef<'tcx>,
@ -76,7 +76,7 @@ pub struct TraitDef<'tcx> {
impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
pub fn new(unsafety: hir::Unsafety,
paren_sugar: bool,
generics: ty::Generics<'tcx>,
generics: &'tcx ty::Generics<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
associated_type_names: Vec<Name>)
-> TraitDef<'tcx> {

View File

@ -11,7 +11,6 @@
//! misc. type-system utilities too small to deserve their own file
use hir::def_id::DefId;
use ty::subst;
use infer::InferCtxt;
use hir::pat_util;
use traits::{self, Reveal};
@ -695,12 +694,10 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
return false;
}
let types_a = substs_a.types.get_slice(subst::TypeSpace);
let types_b = substs_b.types.get_slice(subst::TypeSpace);
let types_a = substs_a.types.as_full_slice();
let types_b = substs_b.types.as_full_slice();
let mut pairs = types_a.iter().zip(types_b);
pairs.all(|(&a, &b)| same_type(a, b))
types_a.iter().zip(types_b).all(|(&a, &b)| same_type(a, b))
}
_ => {
a == b

View File

@ -10,7 +10,7 @@
use hir::def_id::DefId;
use ty::subst::{self, Subst};
use ty::subst::{self, Subst, Substs};
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
use ty::{TyBool, TyChar, TyStruct, TyEnum};
use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
@ -65,69 +65,57 @@ pub enum Ns {
fn number_of_supplied_defaults<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
substs: &subst::Substs,
space: subst::ParamSpace,
generics: ty::Generics<'tcx>)
generics: &ty::Generics<'tcx>)
-> usize
{
let has_self = substs.self_ty().is_some();
let ty_params = generics.types.get_slice(space);
let tps = substs.types.get_slice(space);
if ty_params.last().map_or(false, |def| def.default.is_some()) {
let substs = tcx.lift(&substs);
ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
match def.default {
Some(default) => {
if !has_self && default.has_self_ty() {
// In an object type, there is no `Self`, and
// thus if the default value references Self,
// the user will be required to give an
// explicit value. We can't even do the
// substitution below to check without causing
// an ICE. (#18956).
false
} else {
let default = tcx.lift(&default);
substs.and_then(|substs| default.subst(tcx, substs))
== Some(actual)
}
}
None => false
}
substs.and_then(|substs| def.default.subst(tcx, substs))
== Some(actual)
}).count()
} else {
0
}
}
pub fn parameterized<GG>(f: &mut fmt::Formatter,
substs: &subst::Substs,
did: DefId,
ns: Ns,
projections: &[ty::ProjectionPredicate],
get_generics: GG)
-> fmt::Result
where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>)
-> Option<ty::Generics<'tcx>>
{
if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) {
write!(f, "<{} as ", self_ty)?;
}
pub fn parameterized(f: &mut fmt::Formatter,
substs: &subst::Substs,
did: DefId,
ns: Ns,
projections: &[ty::ProjectionPredicate])
-> fmt::Result {
let (fn_trait_kind, verbose, item_name, is_in_trait) = ty::tls::with(|tcx| {
let is_in_trait = ns == Ns::Value && tcx.trait_of_item(did).is_some();
if is_in_trait {
write!(f, "<{} as ", substs.types.get(subst::SelfSpace, 0))?;
}
let (fn_trait_kind, verbose, item_name) = ty::tls::with(|tcx| {
let (did, item_name) = if ns == Ns::Value {
// Try to get the impl/trait parent, if this is an
// associated value item (method or constant).
tcx.trait_of_item(did).or_else(|| tcx.impl_of_method(did))
.map_or((did, None), |parent| (parent, Some(tcx.item_name(did))))
tcx.trait_of_item(did).or_else(|| {
// An impl could be a trait impl or an inherent one.
tcx.impl_of_method(did).map(|impl_def_id| {
tcx.trait_id_of_impl(impl_def_id)
.unwrap_or(impl_def_id)
})
}).map_or((did, None), |parent| (parent, Some(tcx.item_name(did))))
} else {
(did, None)
};
write!(f, "{}", tcx.item_path_str(did))?;
Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose(), item_name))
Ok((tcx.lang_items.fn_trait_kind(did),
tcx.sess.verbose(),
item_name,
is_in_trait))
})?;
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
let projection_ty = projections[0].ty;
if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
if let TyTuple(ref args) = substs.types.get(subst::TypeSpace, 0).sty {
return fn_sig(f, args, false, projection_ty);
}
}
@ -176,11 +164,8 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
0
} else {
ty::tls::with(|tcx| {
if let Some(generics) = get_generics(tcx) {
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics)
} else {
0
}
let generics = tcx.lookup_generics(did);
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics)
})
};
@ -204,7 +189,7 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
if ns == Ns::Value {
empty.set(true);
if substs.self_ty().is_some() {
if is_in_trait {
write!(f, ">")?;
}
@ -288,7 +273,7 @@ fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter,
/// projection bounds, so we just stuff them altogether. But in
/// reality we should eventually sort things out better.
#[derive(Clone, Debug)]
struct TraitAndProjections<'tcx>(ty::ExistentialTraitRef<'tcx>,
struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>,
Vec<ty::ProjectionPredicate<'tcx>>);
impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
@ -307,8 +292,7 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
parameterized(f, trait_ref.substs,
trait_ref.def_id,
Ns::Type,
projection_bounds,
|tcx| Some(tcx.lookup_trait_def(trait_ref.def_id).generics.clone()))
projection_bounds)
}
}
@ -316,12 +300,16 @@ impl<'tcx> fmt::Display for ty::TraitObject<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Generate the main trait ref, including associated types.
ty::tls::with(|tcx| {
let principal = tcx.lift(&self.principal.0)
.expect("could not lift TraitRef for printing");
// Use a type that can't appear in defaults of type parameters.
let dummy_self = tcx.mk_infer(ty::FreshTy(0));
let principal = tcx.lift(&self.principal)
.expect("could not lift TraitRef for printing")
.with_self_ty(tcx, dummy_self).0;
let projections = self.projection_bounds.iter().map(|p| {
let projection = tcx.lift(p)
.expect("could not lift projection for printing");
projection.with_self_ty(tcx, tcx.types.err).0
tcx.lift(p)
.expect("could not lift projection for printing")
.with_self_ty(tcx, dummy_self).0
}).collect();
let tap = ty::Binder(TraitAndProjections(principal, projections));
@ -380,7 +368,7 @@ impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
}
}
impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
impl<'tcx> fmt::Debug for Substs<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Substs[types={:?}, regions={:?}]",
self.types, self.regions)
@ -404,7 +392,14 @@ impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", *self)
ty::tls::with(|tcx| {
let dummy_self = tcx.mk_infer(ty::FreshTy(0));
let trait_ref = tcx.lift(&ty::Binder(*self))
.expect("could not lift TraitRef for printing")
.with_self_ty(tcx, dummy_self).0;
parameterized(f, trait_ref.substs, trait_ref.def_id, Ns::Type, &[])
})
}
}
@ -813,15 +808,7 @@ impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>>
impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
parameterized(f, self.substs, self.def_id, Ns::Type, &[],
|tcx| Some(tcx.lookup_trait_def(self.def_id).generics.clone()))
}
}
impl<'tcx> fmt::Display for ty::ExistentialTraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
parameterized(f, self.substs, self.def_id, Ns::Type, &[],
|tcx| Some(tcx.lookup_trait_def(self.def_id).generics.clone()))
parameterized(f, self.substs, self.def_id, Ns::Type, &[])
}
}
@ -874,9 +861,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
}
write!(f, "{} {{", bare_fn.sig.0)?;
parameterized(
f, substs, def_id, Ns::Value, &[],
|tcx| tcx.opt_lookup_item_type(def_id).map(|t| t.generics))?;
parameterized(f, substs, def_id, Ns::Value, &[])?;
write!(f, "}}")
}
TyFnPtr(ref bare_fn) => {
@ -899,12 +884,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
!tcx.tcache.borrow().contains_key(&def.did) {
write!(f, "{}<..>", tcx.item_path_str(def.did))
} else {
parameterized(
f, substs, def.did, Ns::Type, &[],
|tcx| {
tcx.opt_lookup_item_type(def.did).
map(|t| t.generics)
})
parameterized(f, substs, def.did, Ns::Type, &[])
}
})
}
@ -916,7 +896,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(|| {
tcx.mk_substs(subst::Substs::empty())
Substs::empty(tcx)
});
let bounds = item_predicates.instantiate(tcx, substs);

View File

@ -859,10 +859,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
let unit_temp = Lvalue::Temp(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 = tcx.mk_substs(Substs::new(
let substs = Substs::new(tcx,
VecPerParamSpace::new(vec![], vec![], vec![ty]),
VecPerParamSpace::new(vec![], vec![], vec![])
));
VecPerParamSpace::new(vec![], vec![], vec![]));
let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
self.patch.new_block(BasicBlockData {

View File

@ -22,8 +22,9 @@ use rustc::traits;
use rustc::hir::def::{Def, PathResolution};
use rustc::hir::def_id::DefId;
use rustc::hir::pat_util::def_to_path;
use rustc::ty::{self, Ty, TyCtxt, subst};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::util::IntTypeExt;
use rustc::ty::subst::Substs;
use rustc::traits::Reveal;
use rustc::util::common::ErrorReported;
use rustc::util::nodemap::NodeMap;
@ -93,7 +94,7 @@ fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
/// This generally happens in late/trans const evaluation.
pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
substs: Option<&'tcx subst::Substs<'tcx>>)
substs: Option<&'tcx Substs<'tcx>>)
-> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)> {
if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
match tcx.map.find(node_id) {
@ -110,7 +111,8 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// If we have a trait item and the substitutions for it,
// `resolve_trait_associated_const` will select an impl
// or the default.
let trait_id = tcx.trait_of_item(def_id).unwrap();
let trait_id = tcx.map.get_parent(node_id);
let trait_id = tcx.map.local_def_id(trait_id);
resolve_trait_associated_const(tcx, ti, trait_id, substs)
} else {
// Technically, without knowing anything about the
@ -1045,16 +1047,14 @@ fn infer<'a, 'tcx>(i: ConstInt,
fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ti: &'tcx hir::TraitItem,
trait_id: DefId,
rcvr_substs: &'tcx subst::Substs<'tcx>)
rcvr_substs: &'tcx Substs<'tcx>)
-> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)>
{
let trait_ref = ty::Binder(
rcvr_substs.clone().erase_regions().to_trait_ref(tcx, trait_id)
);
let trait_ref = ty::Binder(ty::TraitRef::new(trait_id, rcvr_substs));
debug!("resolve_trait_associated_const: trait_ref={:?}",
trait_ref);
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
tcx.populate_implementations_for_trait_if_necessary(trait_id);
tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
let mut selcx = traits::SelectionContext::new(&infcx);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),

View File

@ -21,7 +21,7 @@ use rustc::middle::region::CodeExtentData;
use rustc::middle::resolve_lifetime;
use rustc::middle::stability;
use rustc::ty::subst;
use rustc::ty::subst::Subst;
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
@ -678,8 +678,8 @@ fn subst_ty_renumber_bound() {
env.t_fn(&[t_param], env.t_nil())
};
let substs = subst::Substs::new_type(vec![t_rptr_bound1], vec![]);
let t_substituted = t_source.subst(env.infcx.tcx, &substs);
let substs = Substs::new_type(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = fn(&'a isize)
let t_expected = {
@ -713,8 +713,8 @@ fn subst_ty_renumber_some_bounds() {
env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil()))
};
let substs = subst::Substs::new_type(vec![t_rptr_bound1], vec![]);
let t_substituted = t_source.subst(env.infcx.tcx, &substs);
let substs = Substs::new_type(env.infcx.tcx, vec![t_rptr_bound1], vec![]);
let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = (&'a isize, fn(&'a isize))
//
@ -775,8 +775,8 @@ fn subst_region_renumber_region() {
env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
};
let substs = subst::Substs::new_type(vec![], vec![re_bound1]);
let t_substituted = t_source.subst(env.infcx.tcx, &substs);
let substs = Substs::new_type(env.infcx.tcx, vec![], vec![re_bound1]);
let t_substituted = t_source.subst(env.infcx.tcx, substs);
// t_expected = fn(&'a isize)
//

View File

@ -465,16 +465,14 @@ impl LateLintPass for MissingCopyImplementations {
return;
}
let def = cx.tcx.lookup_adt_def(cx.tcx.map.local_def_id(item.id));
(def, cx.tcx.mk_struct(def,
cx.tcx.mk_substs(Substs::empty())))
(def, cx.tcx.mk_struct(def, Substs::empty(cx.tcx)))
}
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_enum(def,
cx.tcx.mk_substs(Substs::empty())))
(def, cx.tcx.mk_enum(def, Substs::empty(cx.tcx)))
}
_ => return,
};
@ -898,7 +896,7 @@ impl LateLintPass for UnconditionalRecursion {
// A trait method, from any number of possible sources.
// Attempt to select a concrete impl before checking.
ty::TraitContainer(trait_def_id) => {
let trait_ref = callee_substs.to_trait_ref(tcx, trait_def_id);
let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, callee_substs);
let trait_ref = ty::Binder(trait_ref);
let span = tcx.map.span(expr_id);
let obligation =
@ -918,8 +916,7 @@ impl LateLintPass for UnconditionalRecursion {
// If `T` is `Self`, then this call is inside
// a default method definition.
Ok(Some(traits::VtableParam(_))) => {
let self_ty = callee_substs.self_ty();
let on_self = self_ty.map_or(false, |t| t.is_self());
let on_self = trait_ref.self_ty().is_self();
// We can only be recurring in a default
// method if we're being called literally
// on the `Self` type.

View File

@ -34,7 +34,7 @@ use middle::const_qualif::ConstQualif;
use rustc::hir::def::{self, Def};
use rustc::hir::def_id::DefId;
use middle::region;
use rustc::ty::subst;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use syntax::ast;
@ -507,7 +507,7 @@ impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
Ok(this.read_ty(dcx))
}).unwrap(),
substs: this.read_struct_field("substs", 3, |this| {
Ok(dcx.tcx.mk_substs(this.read_substs(dcx)))
Ok(this.read_substs(dcx))
}).unwrap()
}))
}).unwrap()
@ -525,7 +525,7 @@ trait rbml_writer_helpers<'tcx> {
fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region);
fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
fn emit_substs<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
substs: &subst::Substs<'tcx>);
substs: &Substs<'tcx>);
fn emit_upvar_capture(&mut self, ecx: &e::EncodeContext, capture: &ty::UpvarCapture);
fn emit_auto_adjustment<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
adj: &adjustment::AutoAdjustment<'tcx>);
@ -569,7 +569,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
}
fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
substs: &subst::Substs<'tcx>) {
substs: &Substs<'tcx>) {
self.emit_opaque(|this| Ok(tyencode::enc_substs(&mut this.cursor,
&ecx.ty_str_ctxt(),
substs)));
@ -839,7 +839,7 @@ trait rbml_decoder_decoder_helpers<'tcx> {
fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::Predicate<'tcx>;
fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> subst::Substs<'tcx>;
-> &'tcx Substs<'tcx>;
fn read_upvar_capture(&mut self, dcx: &DecodeContext)
-> ty::UpvarCapture;
fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@ -859,7 +859,7 @@ trait rbml_decoder_decoder_helpers<'tcx> {
cdata: &cstore::CrateMetadata) -> Vec<Ty<'tcx>>;
fn read_substs_nodcx<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
cdata: &cstore::CrateMetadata)
-> subst::Substs<'tcx>;
-> &'tcx Substs<'tcx>;
}
impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
@ -884,7 +884,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
fn read_substs_nodcx<'b>(&mut self, tcx: TyCtxt<'b, 'tcx, 'tcx>,
cdata: &cstore::CrateMetadata)
-> subst::Substs<'tcx>
-> &'tcx Substs<'tcx>
{
self.read_opaque(|_, doc| {
Ok(
@ -946,7 +946,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
}
fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> subst::Substs<'tcx> {
-> &'tcx Substs<'tcx> {
self.read_opaque(|_, doc| {
Ok(tydecode::TyDecoder::with_doc(dcx.tcx, dcx.cdata.cnum, doc,
&mut |d| convert_def_id(dcx, d))
@ -1140,7 +1140,7 @@ fn decode_side_tables(dcx: &DecodeContext,
}
c::tag_table_item_subst => {
let item_substs = ty::ItemSubsts {
substs: dcx.tcx.mk_substs(val_dsr.read_substs(dcx))
substs: val_dsr.read_substs(dcx)
};
dcx.tcx.tables.borrow_mut().item_substs.insert(
id, item_substs);

View File

@ -196,16 +196,11 @@ pub const tag_attribute_is_sugared_doc: usize = 0x8c;
// GAP 0x8d
pub const tag_items_data_region: usize = 0x8e;
pub const tag_region_param_def: usize = 0x8f;
pub const tag_region_param_def_ident: usize = 0x90;
pub const tag_region_param_def_def_id: usize = 0x91;
pub const tag_region_param_def_space: usize = 0x92;
pub const tag_region_param_def_index: usize = 0x93;
pub const tag_item_generics: usize = 0x8f;
// GAP 0x90, 0x91, 0x92, 0x93, 0x94
pub const tag_type_param_def: usize = 0x94;
pub const tag_item_generics: usize = 0x95;
pub const tag_method_ty_generics: usize = 0x96;
pub const tag_item_predicates: usize = 0x95;
// GAP 0x96
pub const tag_predicate: usize = 0x97;
// GAP 0x98, 0x99

View File

@ -86,7 +86,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
}
fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::TypeScheme<'tcx>
-> Ty<'tcx>
{
self.dep_graph.read(DepNode::MetaData(def));
let cdata = self.get_crate_data(def.krate);
@ -109,6 +109,14 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
decoder::get_super_predicates(&cdata, def.index, tcx)
}
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> &'tcx ty::Generics<'tcx>
{
self.dep_graph.read(DepNode::MetaData(def));
let cdata = self.get_crate_data(def.krate);
decoder::get_generics(&cdata, def.index, tcx)
}
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>
{
self.dep_graph.read(DepNode::MetaData(def_id));
@ -231,11 +239,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
decoder::get_parent_impl(&*cdata, impl_def.index)
}
fn trait_of_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option<DefId>
{
fn trait_of_item(&self, def_id: DefId) -> Option<DefId> {
self.dep_graph.read(DepNode::MetaData(def_id));
let cdata = self.get_crate_data(def_id.krate);
decoder::get_trait_of_item(&cdata, def_id.index, tcx)
decoder::get_trait_of_item(&cdata, def_id.index)
}
fn impl_or_trait_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)

View File

@ -264,11 +264,6 @@ fn maybe_doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata:
})
}
pub fn item_type<'a, 'tcx>(_item_id: DefId, item: rbml::Doc,
tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) -> Ty<'tcx> {
doc_type(item, tcx, cdata)
}
fn doc_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd)
-> ty::TraitRef<'tcx> {
TyDecoder::with_doc(tcx, cdata.cnum, doc,
@ -383,7 +378,7 @@ pub fn get_trait_def<'a, 'tcx>(cdata: Cmd,
tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::TraitDef<'tcx>
{
let item_doc = cdata.lookup_item(item_id);
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
let generics = doc_generics(item_doc, tcx, cdata);
let unsafety = parse_unsafety(item_doc);
let associated_type_names = parse_associated_type_names(item_doc);
let paren_sugar = parse_paren_sugar(item_doc);
@ -493,7 +488,7 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd,
// from the ctor.
debug!("evaluating the ctor-type of {:?}",
variant.name);
let ctor_ty = get_type(cdata, variant.did.index, tcx).ty;
let ctor_ty = get_type(cdata, variant.did.index, tcx);
debug!("evaluating the ctor-type of {:?}.. {:?}",
variant.name,
ctor_ty);
@ -513,7 +508,7 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd,
} else {
for field in &variant.fields {
debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
let ty = get_type(cdata, field.did.index, tcx).ty;
let ty = get_type(cdata, field.did.index, tcx);
field.fulfill_ty(ty);
debug!("evaluating the type of {:?}::{:?}: {:?}",
variant.name, field.name, ty);
@ -530,7 +525,7 @@ pub fn get_predicates<'a, 'tcx>(cdata: Cmd,
-> ty::GenericPredicates<'tcx>
{
let item_doc = cdata.lookup_item(item_id);
doc_predicates(item_doc, tcx, cdata, tag_item_generics)
doc_predicates(item_doc, tcx, cdata, tag_item_predicates)
}
pub fn get_super_predicates<'a, 'tcx>(cdata: Cmd,
@ -542,17 +537,20 @@ pub fn get_super_predicates<'a, 'tcx>(cdata: Cmd,
doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
}
pub fn get_generics<'a, 'tcx>(cdata: Cmd,
item_id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> &'tcx ty::Generics<'tcx>
{
let item_doc = cdata.lookup_item(item_id);
doc_generics(item_doc, tcx, cdata)
}
pub fn get_type<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> ty::TypeScheme<'tcx>
-> Ty<'tcx>
{
let item_doc = cdata.lookup_item(id);
let t = item_type(DefId { krate: cdata.cnum, index: id }, item_doc, tcx,
cdata);
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
ty::TypeScheme {
generics: generics,
ty: t
}
doc_type(item_doc, tcx, cdata)
}
pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> {
@ -960,8 +958,8 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a
}))
}
Some('r') | Some('p') => {
let generics = doc_generics(item_doc, tcx, cdata, tag_method_ty_generics);
let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics);
let generics = doc_generics(item_doc, tcx, cdata);
let predicates = doc_predicates(item_doc, tcx, cdata, tag_item_predicates);
let ity = tcx.lookup_item_type(def_id).ty;
let fty = match ity.sty {
ty::TyFnDef(_, _, fty) => fty,
@ -1393,10 +1391,7 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
}
}
pub fn get_trait_of_item<'a, 'tcx>(cdata: Cmd,
id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> Option<DefId> {
pub fn get_trait_of_item(cdata: Cmd, id: DefIndex) -> Option<DefId> {
let item_doc = cdata.lookup_item(id);
let parent_item_id = match item_parent_item(cdata, item_doc) {
None => return None,
@ -1405,10 +1400,6 @@ pub fn get_trait_of_item<'a, 'tcx>(cdata: Cmd,
let parent_item_doc = cdata.lookup_item(parent_item_id.index);
match item_family(parent_item_doc) {
Trait => Some(item_def_id(parent_item_doc, cdata)),
Impl | DefaultImpl => {
reader::maybe_get_doc(parent_item_doc, tag_item_trait_ref)
.map(|_| item_trait_ref(parent_item_doc, tcx, cdata).def_id)
}
_ => None
}
}
@ -1537,11 +1528,7 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd,
};
let applicable = match item_family(item_doc) {
ImmStatic | MutStatic => true,
Fn => {
let ty::TypeScheme { generics, .. } = get_type(cdata, id, tcx);
let no_generics = generics.types.is_empty();
no_generics
},
Fn => get_generics(cdata, id, tcx).types.is_empty(),
_ => false,
};
@ -1573,30 +1560,13 @@ pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
fn doc_generics<'a, 'tcx>(base_doc: rbml::Doc,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
cdata: Cmd,
tag: usize)
-> ty::Generics<'tcx>
cdata: Cmd)
-> &'tcx ty::Generics<'tcx>
{
let doc = reader::get_doc(base_doc, tag);
let mut generics = ty::Generics::empty();
for p in reader::tagged_docs(doc, tag_type_param_def) {
let bd =
TyDecoder::with_doc(tcx, cdata.cnum, p,
&mut |did| translate_def_id(cdata, did))
.parse_type_param_def();
generics.types.push(bd.space, bd);
}
for p in reader::tagged_docs(doc, tag_region_param_def) {
let bd =
TyDecoder::with_doc(tcx, cdata.cnum, p,
&mut |did| translate_def_id(cdata, did))
.parse_region_param_def();
generics.regions.push(bd.space, bd);
}
generics
let doc = reader::get_doc(base_doc, tag_item_generics);
TyDecoder::with_doc(tcx, cdata.cnum, doc,
&mut |did| translate_def_id(cdata, did))
.parse_generics()
}
fn doc_predicate<'a, 'tcx>(cdata: Cmd,

View File

@ -175,8 +175,7 @@ fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
index: &mut CrateIndex<'a, 'tcx>,
scheme: &ty::TypeScheme<'tcx>,
predicates: &ty::GenericPredicates<'tcx>) {
encode_generics(rbml_w, ecx, index,
&scheme.generics, &predicates, tag_item_generics);
encode_generics(rbml_w, ecx, index, &scheme.generics, &predicates);
encode_type(ecx, rbml_w, scheme.ty);
}
@ -510,50 +509,26 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>,
index: &mut CrateIndex<'a, 'tcx>,
generics: &ty::Generics<'tcx>,
predicates: &ty::GenericPredicates<'tcx>,
tag: usize)
predicates: &ty::GenericPredicates<'tcx>)
{
rbml_w.start_tag(tag);
for param in generics.types.as_full_slice() {
rbml_w.start_tag(tag_type_param_def);
tyencode::enc_type_param_def(rbml_w.writer, &ecx.ty_str_ctxt(), param);
rbml_w.mark_stable_position();
rbml_w.end_tag();
}
// Region parameters
for param in generics.regions.as_full_slice() {
rbml_w.start_tag(tag_region_param_def);
tyencode::enc_region_param_def(rbml_w.writer, &ecx.ty_str_ctxt(), param);
rbml_w.mark_stable_position();
rbml_w.end_tag();
}
encode_predicates_in_current_doc(rbml_w, ecx, index, predicates);
rbml_w.start_tag(tag_item_generics);
tyencode::enc_generics(rbml_w.writer, &ecx.ty_str_ctxt(), generics);
rbml_w.mark_stable_position();
rbml_w.end_tag();
}
fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
_ecx: &EncodeContext<'a,'tcx>,
index: &mut CrateIndex<'a, 'tcx>,
predicates: &ty::GenericPredicates<'tcx>)
{
for predicate in &predicates.predicates {
rbml_w.wr_tagged_u32(tag_predicate,
index.add_xref(XRef::Predicate(predicate.clone())));
}
encode_predicates(rbml_w, index, predicates, tag_item_predicates);
}
fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a,'tcx>,
index: &mut CrateIndex<'a, 'tcx>,
predicates: &ty::GenericPredicates<'tcx>,
tag: usize)
{
rbml_w.start_tag(tag);
encode_predicates_in_current_doc(rbml_w, ecx, index, predicates);
for predicate in &predicates.predicates {
rbml_w.wr_tagged_u32(tag_predicate,
index.add_xref(XRef::Predicate(predicate.clone())));
}
rbml_w.end_tag();
}
@ -564,8 +539,7 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_def_id_and_key(ecx, rbml_w, method_ty.def_id);
encode_name(rbml_w, method_ty.name);
encode_generics(rbml_w, ecx, index,
&method_ty.generics, &method_ty.predicates,
tag_method_ty_generics);
&method_ty.generics, &method_ty.predicates);
encode_visibility(rbml_w, method_ty.vis);
encode_explicit_self(rbml_w, &method_ty.explicit_self);
match method_ty.explicit_self {
@ -695,7 +669,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_attributes(rbml_w, &ii.attrs);
encode_defaultness(rbml_w, ii.defaultness);
} else {
encode_predicates(rbml_w, ecx, index,
encode_predicates(rbml_w, index,
&ecx.tcx.lookup_predicates(associated_type.def_id),
tag_item_generics);
}
@ -1134,9 +1108,8 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id));
encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
encode_generics(rbml_w, ecx, index,
&trait_def.generics, &trait_predicates,
tag_item_generics);
encode_predicates(rbml_w, ecx, index,
&trait_def.generics, &trait_predicates);
encode_predicates(rbml_w, index,
&tcx.lookup_super_predicates(def_id),
tag_item_super_predicates);
encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);

View File

@ -74,7 +74,7 @@ impl<'a, 'tcx: 'a> tls::DecodingContext<'tcx> for DecodingContext<'a, 'tcx> {
ty
}
fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx> {
fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> &'tcx Substs<'tcx> {
let def_id_convert = &mut |did| {
decoder::translate_def_id(self.crate_metadata, did)
};

View File

@ -20,8 +20,7 @@ use rustc::hir;
use rustc::hir::def_id::{DefId, DefIndex};
use middle::region;
use rustc::ty::subst;
use rustc::ty::subst::VecPerParamSpace;
use rustc::ty::subst::{self, Substs, VecPerParamSpace};
use rustc::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
use rbml;
@ -132,21 +131,31 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
{
let mut r = VecPerParamSpace::empty();
for &space in &subst::ParamSpace::all() {
let (mut a, mut b, mut c) = (vec![], vec![], vec![]);
for r in &mut [&mut a, &mut b, &mut c] {
assert_eq!(self.next(), '[');
while self.peek() != ']' {
r.push(space, f(self));
r.push(f(self));
}
assert_eq!(self.next(), ']');
}
r
VecPerParamSpace::new(a, b, c)
}
pub fn parse_substs(&mut self) -> subst::Substs<'tcx> {
pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
let regions = self.parse_vec_per_param_space(|this| this.parse_region());
let types = self.parse_vec_per_param_space(|this| this.parse_ty());
subst::Substs { types: types, regions: regions }
Substs::new(self.tcx, types, regions)
}
pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> {
let regions = self.parse_vec_per_param_space(|this| this.parse_region_param_def());
let types = self.parse_vec_per_param_space(|this| this.parse_type_param_def());
self.tcx.alloc_generics(ty::Generics {
regions: regions,
types: types,
has_self: self.next() == 'S'
})
}
fn parse_bound_region(&mut self) -> ty::BoundRegion {
@ -302,15 +311,17 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
let def = self.parse_def();
let substs = self.tcx.mk_substs(self.parse_substs());
ty::TraitRef {def_id: def, substs: substs}
ty::TraitRef {
def_id: self.parse_def(),
substs: self.parse_substs()
}
}
pub fn parse_existential_trait_ref(&mut self) -> ty::ExistentialTraitRef<'tcx> {
let def = self.parse_def();
let substs = self.tcx.mk_substs(self.parse_substs());
ty::ExistentialTraitRef {def_id: def, substs: substs}
ty::ExistentialTraitRef {
def_id: self.parse_def(),
substs: self.parse_substs()
}
}
pub fn parse_ty(&mut self) -> Ty<'tcx> {
@ -342,7 +353,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
let substs = self.parse_substs();
assert_eq!(self.next(), ']');
let def = self.tcx.lookup_adt_def(did);
return tcx.mk_enum(def, self.tcx.mk_substs(substs));
return tcx.mk_enum(def, substs);
}
'x' => {
assert_eq!(self.next(), '[');
@ -406,7 +417,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
'F' => {
let def_id = self.parse_def();
let substs = self.tcx.mk_substs(self.parse_substs());
let substs = self.parse_substs();
return tcx.mk_fn_def(def_id, substs, self.parse_bare_fn_ty());
}
'G' => {
@ -452,7 +463,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
let substs = self.parse_substs();
assert_eq!(self.next(), ']');
let def = self.tcx.lookup_adt_def(did);
return self.tcx.mk_struct(def, self.tcx.mk_substs(substs));
return self.tcx.mk_struct(def, substs);
}
'k' => {
assert_eq!(self.next(), '[');
@ -464,7 +475,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
assert_eq!(self.next(), '.');
assert_eq!(self.next(), ']');
return self.tcx.mk_closure(did, self.tcx.mk_substs(substs), tys);
return self.tcx.mk_closure(did, substs, tys);
}
'P' => {
assert_eq!(self.next(), '[');
@ -477,7 +488,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
let def_id = self.parse_def();
let substs = self.parse_substs();
assert_eq!(self.next(), ']');
return self.tcx.mk_anon(def_id, self.tcx.mk_substs(substs));
return self.tcx.mk_anon(def_id, substs);
}
'e' => {
return tcx.types.err;
@ -622,7 +633,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
let name = self.parse_name(':');
let def_id = self.parse_def();
let space = self.parse_param_space();
@ -644,7 +655,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
let name = self.parse_name(':');
let def_id = self.parse_def();
let space = self.parse_param_space();

View File

@ -19,8 +19,7 @@ use std::io::prelude::*;
use rustc::hir::def_id::DefId;
use middle::region;
use rustc::ty::subst;
use rustc::ty::subst::VecPerParamSpace;
use rustc::ty::subst::{self, Substs, VecPerParamSpace};
use rustc::ty::ParamTy;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::util::nodemap::FnvHashMap;
@ -266,13 +265,27 @@ fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Cursor<Vec<u8>>,
}
pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
substs: &subst::Substs<'tcx>) {
substs: &Substs<'tcx>) {
enc_vec_per_param_space(w, cx, &substs.regions,
|w, cx, &r| enc_region(w, cx, r));
enc_vec_per_param_space(w, cx, &substs.types,
|w, cx, &ty| enc_ty(w, cx, ty));
}
pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
generics: &ty::Generics<'tcx>) {
enc_vec_per_param_space(w, cx, &generics.regions,
|w, cx, r| enc_region_param_def(w, cx, r));
enc_vec_per_param_space(w, cx, &generics.types,
|w, cx, ty| enc_type_param_def(w, cx, ty));
if generics.has_self {
write!(w, "S");
} else {
write!(w, "N");
}
}
pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: ty::Region) {
match r {
ty::ReLateBound(id, br) => {
@ -420,8 +433,8 @@ fn enc_builtin_bounds(w: &mut Cursor<Vec<u8>>, _cx: &ctxt, bs: &ty::BuiltinBound
write!(w, ".");
}
pub fn enc_type_param_def<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
fn enc_type_param_def<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
write!(w, "{}:{}|{}|{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id),
v.space.to_uint(), v.index, (cx.ds)(cx.tcx, v.default_def_id));
@ -429,8 +442,8 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}
pub fn enc_region_param_def(w: &mut Cursor<Vec<u8>>, cx: &ctxt,
v: &ty::RegionParameterDef) {
fn enc_region_param_def(w: &mut Cursor<Vec<u8>>, cx: &ctxt,
v: &ty::RegionParameterDef) {
write!(w, "{}:{}|{}|{}|",
v.name, (cx.ds)(cx.tcx, v.def_id),
v.space.to_uint(), v.index);

View File

@ -750,7 +750,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 = tcx.mk_substs(Substs::new_fn(vec![data.item_ty], vec![]));
let substs = Substs::new_fn(tcx, vec![data.item_ty], vec![]);
TerminatorKind::Call {
func: Operand::Constant(Constant {
span: data.span,

View File

@ -147,16 +147,16 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
params: Vec<Ty<'tcx>>)
-> (Ty<'tcx>, Literal<'tcx>) {
let method_name = token::intern(method_name);
let substs = Substs::new_trait(params, vec![], self_ty);
let substs = Substs::new_trait(self.tcx, params, vec![], self_ty);
for trait_item in self.tcx.trait_items(trait_def_id).iter() {
match *trait_item {
ty::ImplOrTraitItem::MethodTraitItem(ref method) => {
if method.name == method_name {
let method_ty = self.tcx.lookup_item_type(method.def_id);
let method_ty = method_ty.ty.subst(self.tcx, &substs);
let method_ty = method_ty.ty.subst(self.tcx, substs);
return (method_ty, Literal::Item {
def_id: method.def_id,
substs: self.tcx.mk_substs(substs),
substs: substs,
});
}
}

View File

@ -299,8 +299,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
let mut result = String::from("<");
result.push_str(&rustc::hir::print::ty_to_string(&ty));
if let Some(def_id) = self.tcx
.trait_of_item(self.tcx.map.local_def_id(id)) {
if let Some(def_id) = self.tcx.trait_id_of_impl(impl_id) {
result.push_str(" as ");
result.push_str(&self.tcx.item_path_str(def_id));
}

View File

@ -895,7 +895,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
&format!("comparison of `{}`", rhs_t),
StrEqFnLangItem);
let args = [lhs_data, lhs_len, rhs_data, rhs_len];
Callee::def(bcx.ccx(), did, bcx.tcx().mk_substs(Substs::empty()))
Callee::def(bcx.ccx(), did, Substs::empty(bcx.tcx()))
.call(bcx, debug_loc, ArgVals(&args), None)
}

View File

@ -48,7 +48,7 @@ use std;
use std::rc::Rc;
use llvm::{ValueRef, True, IntEQ, IntNE};
use rustc::ty::subst;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use syntax::ast;
use syntax::attr;
@ -544,7 +544,7 @@ impl<'tcx> Case<'tcx> {
fn get_cases<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
adt: ty::AdtDef<'tcx>,
substs: &subst::Substs<'tcx>)
substs: &Substs<'tcx>)
-> Vec<Case<'tcx>> {
adt.variants.iter().map(|vi| {
let field_tys = vi.fields.iter().map(|field| {

View File

@ -218,7 +218,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, bcx.tcx().mk_substs(Substs::empty()))
let r = Callee::def(bcx.ccx(), def_id, Substs::empty(bcx.tcx()))
.call(bcx, debug_loc, ArgVals(&[size, align]), None);
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
@ -670,11 +670,9 @@ pub fn custom_coerce_unsize_info<'scx, 'tcx>(scx: &SharedCrateContext<'scx, 'tcx
source_ty: Ty<'tcx>,
target_ty: Ty<'tcx>)
-> CustomCoerceUnsized {
let trait_substs = Substs::new_trait(vec![target_ty], vec![], source_ty);
let trait_ref = ty::Binder(ty::TraitRef {
def_id: scx.tcx().lang_items.coerce_unsized_trait().unwrap(),
substs: scx.tcx().mk_substs(trait_substs)
substs: Substs::new_trait(scx.tcx(), vec![target_ty], vec![], source_ty)
});
match fulfill_obligation(scx, DUMMY_SP, trait_ref) {
@ -1410,7 +1408,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
common::validate_substs(instance.substs);
(instance.substs, Some(instance.def), Some(inlined_id))
}
None => (ccx.tcx().mk_substs(Substs::empty()), None, None)
None => (Substs::empty(ccx.tcx()), None, None)
};
let local_id = def_id.and_then(|id| ccx.tcx().map.as_local_node_id(id));
@ -2175,7 +2173,7 @@ pub fn maybe_create_entry_wrapper(ccx: &CrateContext) {
Ok(id) => id,
Err(s) => ccx.sess().fatal(&s)
};
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
let empty_substs = Substs::empty(ccx.tcx());
let start_fn = Callee::def(ccx, start_def_id, empty_substs).reify(ccx).val;
let args = {
let opaque_rust_main =

View File

@ -22,7 +22,7 @@ use back::symbol_names;
use llvm::{self, ValueRef, get_params};
use middle::cstore::LOCAL_CRATE;
use rustc::hir::def_id::DefId;
use rustc::ty::subst;
use rustc::ty::subst::Substs;
use rustc::traits;
use rustc::hir::map as hir_map;
use abi::{Abi, FnType};
@ -105,13 +105,12 @@ impl<'tcx> Callee<'tcx> {
/// Function or method definition.
pub fn def<'a>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
substs: &'tcx Substs<'tcx>)
-> Callee<'tcx> {
let tcx = ccx.tcx();
if substs.self_ty().is_some() {
// Only trait methods can have a Self parameter.
return Callee::trait_method(ccx, def_id, substs);
if let Some(trait_id) = tcx.trait_of_item(def_id) {
return Callee::trait_method(ccx, trait_id, def_id, substs);
}
let maybe_node_id = inline::get_local_instance(ccx, def_id)
@ -144,24 +143,21 @@ impl<'tcx> Callee<'tcx> {
/// Trait method, which has to be resolved to an impl method.
pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>,
trait_id: DefId,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
substs: &'tcx Substs<'tcx>)
-> Callee<'tcx> {
let tcx = ccx.tcx();
let method_item = tcx.impl_or_trait_item(def_id);
let trait_id = method_item.container().id();
let trait_ref = ty::Binder(substs.to_trait_ref(tcx, trait_id));
let trait_ref = tcx.normalize_associated_type(&trait_ref);
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, substs);
let trait_ref = tcx.normalize_associated_type(&ty::Binder(trait_ref));
match common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) {
traits::VtableImpl(vtable_impl) => {
let impl_did = vtable_impl.impl_def_id;
let mname = tcx.item_name(def_id);
// create a concatenated set of substitutions which includes
// those from the impl and those from the method:
let impl_substs = vtable_impl.substs.with_method_from(&substs);
let substs = tcx.mk_substs(impl_substs);
let mth = meth::get_impl_method(tcx, impl_did, substs, mname);
let mth = meth::get_impl_method(tcx, substs, impl_did, vtable_impl.substs, mname);
// Translate the function, bypassing Callee::def.
// That is because default methods have the same ID as the
@ -275,7 +271,7 @@ impl<'tcx> Callee<'tcx> {
/// Given a DefId and some Substs, produces the monomorphic item type.
fn def_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
substs: &'tcx Substs<'tcx>)
-> Ty<'tcx> {
let ty = tcx.lookup_item_type(def_id).ty;
monomorphize::apply_param_substs(tcx, substs, &ty)
@ -427,7 +423,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
/// - `substs`: values for each of the fn/method's parameters
fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
def_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
substs: &'tcx Substs<'tcx>)
-> Datum<'tcx, Rvalue> {
let tcx = ccx.tcx();

View File

@ -732,7 +732,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
create_fn_trans_item(scx.tcx(),
exchange_free_fn_def_id,
fn_substs,
scx.tcx().mk_substs(Substs::empty()));
Substs::empty(scx.tcx()));
output.push(exchange_free_fn_trans_item);
}
@ -753,8 +753,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
.drop_trait()
.unwrap();
let self_type_substs = scx.tcx().mk_substs(
Substs::empty().with_self_ty(ty));
let self_type_substs = Substs::new_trait(scx.tcx(), vec![], vec![], ty);
let trait_ref = ty::TraitRef {
def_id: drop_trait_def_id,
@ -770,7 +769,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
let trans_item = create_fn_trans_item(scx.tcx(),
destructor_did,
substs,
scx.tcx().mk_substs(Substs::empty()));
Substs::empty(scx.tcx()));
output.push(trans_item);
}
@ -854,26 +853,15 @@ fn do_static_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
fn_substs,
param_substs);
let is_trait_method = scx.tcx().trait_of_item(fn_def_id).is_some();
if is_trait_method {
if let Some(trait_def_id) = scx.tcx().trait_of_item(fn_def_id) {
match scx.tcx().impl_or_trait_item(fn_def_id) {
ty::MethodTraitItem(ref method) => {
match method.container {
ty::TraitContainer(trait_def_id) => {
debug!(" => trait method, attempting to find impl");
do_static_trait_method_dispatch(scx,
method,
trait_def_id,
fn_substs,
param_substs)
}
ty::ImplContainer(_) => {
// This is already a concrete implementation
debug!(" => impl method");
Some((fn_def_id, fn_substs))
}
}
debug!(" => trait method, attempting to find impl");
do_static_trait_method_dispatch(scx,
method,
trait_def_id,
fn_substs,
param_substs)
}
_ => bug!()
}
@ -903,13 +891,12 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
callee_substs,
param_substs);
let rcvr_substs = monomorphize::apply_param_substs(tcx,
param_substs,
&callee_substs);
let trait_ref = ty::Binder(rcvr_substs.to_trait_ref(tcx, trait_id));
let trait_ref = tcx.normalize_associated_type(&trait_ref);
let vtbl = fulfill_obligation(scx, DUMMY_SP, trait_ref);
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
let vtbl = fulfill_obligation(scx, DUMMY_SP, ty::Binder(trait_ref));
// Now that we know which impl is being used, we can dispatch to
// the actual function:
@ -919,10 +906,10 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
substs: impl_substs,
nested: _ }) =>
{
let callee_substs = impl_substs.with_method_from(&rcvr_substs);
let impl_method = meth::get_impl_method(tcx,
rcvr_substs,
impl_did,
tcx.mk_substs(callee_substs),
impl_substs,
trait_method.name);
Some((impl_method.method.def_id, &impl_method.substs))
}
@ -1076,7 +1063,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a,
Some(create_fn_trans_item(scx.tcx(),
impl_method.method.def_id,
impl_method.substs,
scx.tcx().mk_substs(Substs::empty())))
Substs::empty(scx.tcx())))
} else {
None
}
@ -1248,9 +1235,13 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// The substitutions we have are on the impl, so we grab
// the method type from the impl to substitute into.
let impl_substs = Substs::for_item(tcx, impl_def_id,
|_, _| ty::ReErased,
|_, _| tcx.types.err);
let mth = meth::get_impl_method(tcx,
impl_def_id,
callee_substs,
impl_def_id,
impl_substs,
default_impl.name);
assert!(mth.is_provided);

View File

@ -523,7 +523,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, tcx.mk_substs(Substs::empty())).reify(ccx).val
Callee::def(ccx, def_id, Substs::empty(tcx)).reify(ccx).val
}
_ => {
if let Some(llpersonality) = ccx.eh_personality().get() {
@ -550,7 +550,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, tcx.mk_substs(Substs::empty()));
return Callee::def(ccx, def_id, Substs::empty(tcx));
}
let ty = tcx.mk_fn_ptr(tcx.mk_bare_fn(ty::BareFnTy {

View File

@ -208,7 +208,7 @@ fn const_fn_call<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let arg_ids = args.iter().map(|arg| arg.pat.id);
let fn_args = arg_ids.zip(arg_vals.iter().cloned()).collect();
let substs = ccx.tcx().mk_substs(substs.clone().erase_regions());
let substs = ccx.tcx().erase_regions(&substs);
let substs = monomorphize::apply_param_substs(ccx.tcx(),
param_substs,
&substs);
@ -222,7 +222,7 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
param_substs: &'tcx Substs<'tcx>)
-> &'tcx hir::Expr {
let substs = ccx.tcx().node_id_item_substs(ref_expr.id).substs;
let substs = ccx.tcx().mk_substs(substs.clone().erase_regions());
let substs = ccx.tcx().erase_regions(&substs);
let substs = monomorphize::apply_param_substs(ccx.tcx(),
param_substs,
&substs);
@ -271,7 +271,7 @@ fn get_const_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
param_substs: &'tcx Substs<'tcx>)
-> Result<ValueRef, ConstEvalFailure> {
let expr = get_const_expr(ccx, def_id, ref_expr, param_substs);
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
let empty_substs = Substs::empty(ccx.tcx());
match get_const_expr_as_global(ccx, expr, ConstQualif::empty(), empty_substs, TrueConst::Yes) {
Err(Runtime(err)) => {
report_const_eval_err(ccx.tcx(), &err, expr.span, "expression").emit();
@ -1160,7 +1160,7 @@ pub fn trans_static(ccx: &CrateContext,
let v = if use_mir {
::mir::trans_static_initializer(ccx, def_id)
} else {
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
let empty_substs = Substs::empty(ccx.tcx());
const_expr(ccx, expr, empty_substs, None, TrueConst::Yes)
.map(|(v, _)| v)
}.map_err(|e| e.into_inner())?;

View File

@ -30,7 +30,7 @@ use monomorphize::Instance;
use partitioning::CodegenUnit;
use trans_item::TransItem;
use type_::{Type, TypeNames};
use rustc::ty::subst::{Substs, VecPerParamSpace};
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt};
use session::config::NoDebugInfo;
use session::Session;
@ -571,16 +571,9 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
/// Given the def-id of some item that has no type parameters, make
/// a suitable "empty substs" for it.
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
let scheme = self.tcx().lookup_item_type(item_def_id);
self.empty_substs_for_scheme(&scheme)
}
pub fn empty_substs_for_scheme(&self, scheme: &ty::TypeScheme<'tcx>)
-> &'tcx Substs<'tcx> {
assert!(scheme.generics.types.is_empty());
self.tcx().mk_substs(
Substs::new(VecPerParamSpace::empty(),
scheme.generics.regions.map(|_| ty::ReErased)))
Substs::for_item(self.tcx(), item_def_id, |_, _| ty::ReErased, |_, _| {
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
})
}
pub fn symbol_hasher(&self) -> &RefCell<Sha256> {
@ -999,11 +992,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
self.shared().empty_substs_for_def_id(item_def_id)
}
pub fn empty_substs_for_scheme(&self, scheme: &ty::TypeScheme<'tcx>)
-> &'tcx Substs<'tcx> {
self.shared().empty_substs_for_scheme(scheme)
}
}
pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);

View File

@ -401,7 +401,7 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let expr_file_line = consts::addr_of(ccx, expr_file_line_const, align, "panic_loc");
let args = vec!(expr_file_line);
let did = langcall(bcx.tcx(), Some(call_info.span), "", PanicFnLangItem);
Callee::def(ccx, did, ccx.tcx().mk_substs(Substs::empty()))
Callee::def(ccx, did, Substs::empty(ccx.tcx()))
.call(bcx, call_info.debug_loc(), ArgVals(&args), None).bcx
}
@ -429,6 +429,6 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let file_line = consts::addr_of(ccx, file_line_const, align, "panic_bounds_check_loc");
let args = vec!(file_line, index, len);
let did = langcall(bcx.tcx(), Some(call_info.span), "", PanicBoundsCheckFnLangItem);
Callee::def(ccx, did, ccx.tcx().mk_substs(Substs::empty()))
Callee::def(ccx, did, Substs::empty(ccx.tcx()))
.call(bcx, call_info.debug_loc(), ArgVals(&args), None).bcx
}

View File

@ -27,7 +27,7 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
use rustc::hir::def_id::DefId;
use rustc::hir::pat_util;
use rustc::ty::subst;
use rustc::ty::subst::Substs;
use rustc::hir::map as hir_map;
use rustc::hir::{self, PatKind};
use {type_of, adt, machine, monomorphize};
@ -315,7 +315,7 @@ impl<'tcx> TypeMap<'tcx> {
fn from_def_id_and_substs<'a, 'tcx>(type_map: &mut TypeMap<'tcx>,
cx: &CrateContext<'a, 'tcx>,
def_id: DefId,
substs: &subst::Substs<'tcx>,
substs: &Substs<'tcx>,
output: &mut String) {
// First, find out the 'real' def_id of the type. Items inlined from
// other crates have to be mapped back to their source.
@ -346,7 +346,7 @@ impl<'tcx> TypeMap<'tcx> {
// Add the def-index as the second part
output.push_str(&format!("{:x}", def_id.index.as_usize()));
let tps = substs.types.get_slice(subst::TypeSpace);
let tps = substs.types.as_full_slice();
if !tps.is_empty() {
output.push('<');
@ -1086,7 +1086,7 @@ impl<'tcx> MemberDescriptionFactory<'tcx> {
// Creates MemberDescriptions for the fields of a struct
struct StructMemberDescriptionFactory<'tcx> {
variant: ty::VariantDef<'tcx>,
substs: &'tcx subst::Substs<'tcx>,
substs: &'tcx Substs<'tcx>,
is_simd: bool,
span: Span,
}

View File

@ -266,7 +266,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// Get_template_parameters() will append a `<...>` clause to the function
// name if necessary.
let generics = cx.tcx().lookup_item_type(fn_def_id).generics;
let generics = cx.tcx().lookup_generics(fn_def_id);
let template_parameters = get_template_parameters(cx,
&generics,
instance.substs,

View File

@ -12,7 +12,7 @@
use common::CrateContext;
use rustc::hir::def_id::DefId;
use rustc::ty::subst;
use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty};
use rustc::hir;
@ -173,7 +173,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// would be possible but with inlining and LTO we have to use the least
// common denominator - otherwise we would run into conflicts.
fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
substs: &subst::Substs<'tcx>,
substs: &Substs<'tcx>,
output: &mut String) {
if substs.types.is_empty() {
return;

View File

@ -175,7 +175,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
hir::ExprPath(..) => {
match bcx.tcx().expect_def(expr.id) {
Def::Const(did) | Def::AssociatedConst(did) => {
let empty_substs = bcx.tcx().mk_substs(Substs::empty());
let empty_substs = Substs::empty(bcx.tcx());
let const_expr = consts::get_const_expr(bcx.ccx(), did, expr,
empty_substs);
// Temporarily get cleanup scopes out of the way,

View File

@ -50,7 +50,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, bcx.tcx().mk_substs(Substs::empty()))
Callee::def(bcx.ccx(), def_id, Substs::empty(bcx.tcx()))
.call(bcx, debug_loc, ArgVals(&args), None).bcx
}
@ -356,7 +356,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let trait_ref = ty::Binder(ty::TraitRef {
def_id: tcx.lang_items.drop_trait().unwrap(),
substs: tcx.mk_substs(Substs::empty().with_self_ty(t))
substs: Substs::new_trait(tcx, vec![], vec![], t)
});
let vtbl = match fulfill_obligation(bcx.ccx().shared(), DUMMY_SP, trait_ref) {
traits::VtableImpl(data) => data,

View File

@ -15,8 +15,7 @@ use intrinsics::{self, Intrinsic};
use libc;
use llvm;
use llvm::{ValueRef, TypeKind};
use rustc::ty::subst;
use rustc::ty::subst::FnSpace;
use rustc::ty::subst::{FnSpace, Substs};
use abi::{Abi, FnType};
use adt;
use base::*;
@ -1284,7 +1283,7 @@ fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
fn generic_simd_intrinsic<'blk, 'tcx, 'a>
(bcx: Block<'blk, 'tcx>,
name: &str,
substs: &'tcx subst::Substs<'tcx>,
substs: &'tcx Substs<'tcx>,
callee_ty: Ty<'tcx>,
args: Option<&[P<hir::Expr>]>,
llargs: &[ValueRef],

View File

@ -15,8 +15,7 @@ use arena::TypedArena;
use back::symbol_names;
use llvm::{ValueRef, get_params};
use rustc::hir::def_id::DefId;
use rustc::ty::subst::{FnSpace, Subst, Substs};
use rustc::ty::subst;
use rustc::ty::subst::{Subst, Substs};
use rustc::traits::{self, Reveal};
use abi::FnType;
use base::*;
@ -221,20 +220,20 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_id: DefId,
substs: &'tcx subst::Substs<'tcx>)
substs: &'tcx Substs<'tcx>)
-> Vec<Option<ImplMethod<'tcx>>>
{
debug!("get_vtable_methods(impl_id={:?}, substs={:?}", impl_id, substs);
let trt_id = match tcx.impl_trait_ref(impl_id) {
let trait_id = match tcx.impl_trait_ref(impl_id) {
Some(t_id) => t_id.def_id,
None => bug!("make_impl_vtable: don't know how to \
make a vtable for a type impl!")
};
tcx.populate_implementations_for_trait_if_necessary(trt_id);
tcx.populate_implementations_for_trait_if_necessary(trait_id);
let trait_item_def_ids = tcx.trait_item_def_ids(trt_id);
let trait_item_def_ids = tcx.trait_item_def_ids(trait_id);
trait_item_def_ids
.iter()
@ -260,7 +259,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let name = trait_method_type.name;
// Some methods cannot be called on an object; skip those.
if !tcx.is_vtable_safe_method(trt_id, &trait_method_type) {
if !tcx.is_vtable_safe_method(trait_id, &trait_method_type) {
debug!("get_vtable_methods: not vtable safe");
return None;
}
@ -270,15 +269,13 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// the method may have some early-bound lifetimes, add
// regions for those
let num_dummy_regions = trait_method_type.generics.regions.len(FnSpace);
let dummy_regions = vec![ty::ReErased; num_dummy_regions];
let method_substs = substs.clone()
.with_method(vec![], dummy_regions);
let method_substs = tcx.mk_substs(method_substs);
let method_substs = Substs::for_item(tcx, trait_method_def_id,
|_, _| ty::ReErased,
|_, _| tcx.types.err);
// The substitutions we have are on the impl, so we grab
// the method type from the impl to substitute into.
let mth = get_impl_method(tcx, impl_id, method_substs, name);
let mth = get_impl_method(tcx, method_substs, impl_id, substs, name);
debug!("get_vtable_methods: mth={:?}", mth);
@ -309,8 +306,9 @@ pub struct ImplMethod<'tcx> {
/// Locates the applicable definition of a method, given its name.
pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impl_def_id: DefId,
substs: &'tcx Substs<'tcx>,
impl_def_id: DefId,
impl_substs: &'tcx Substs<'tcx>,
name: Name)
-> ImplMethod<'tcx>
{
@ -322,6 +320,7 @@ pub fn get_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
match trait_def.ancestors(impl_def_id).fn_defs(tcx, name).next() {
Some(node_item) => {
let substs = tcx.normalizing_infer_ctxt(Reveal::All).enter(|infcx| {
let substs = substs.rebase_onto(tcx, trait_def_id, impl_substs);
let substs = traits::translate_substs(&infcx, impl_def_id,
substs, node_item.node);
tcx.lift(&substs).unwrap_or_else(|| {

View File

@ -232,12 +232,9 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
args: IndexVec<mir::Arg, Const<'tcx>>)
-> Result<Const<'tcx>, ConstEvalFailure> {
// Try to resolve associated constants.
if instance.substs.self_ty().is_some() {
// Only trait items can have a Self parameter.
let trait_item = ccx.tcx().impl_or_trait_item(instance.def);
let trait_id = trait_item.container().id();
let substs = instance.substs;
let trait_ref = ty::Binder(substs.to_trait_ref(ccx.tcx(), trait_id));
if let Some(trait_id) = ccx.tcx().trait_of_item(instance.def) {
let trait_ref = ty::TraitRef::new(trait_id, instance.substs);
let trait_ref = ty::Binder(trait_ref);
let vtable = common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref);
if let traits::VtableImpl(vtable_impl) = vtable {
let name = ccx.tcx().item_name(instance.def);

View File

@ -12,7 +12,6 @@ use llvm::ValueRef;
use llvm;
use rustc::hir::def_id::DefId;
use rustc::infer::TransNormalize;
use rustc::ty::subst;
use rustc::ty::subst::{Subst, Substs};
use rustc::ty::{self, Ty, TypeFoldable, TyCtxt};
use attributes;
@ -33,7 +32,7 @@ use trans_item::TransItem;
pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
fn_id: DefId,
psubsts: &'tcx subst::Substs<'tcx>)
psubsts: &'tcx Substs<'tcx>)
-> (ValueRef, Ty<'tcx>) {
debug!("monomorphic_fn(fn_id={:?}, real_substs={:?})", fn_id, psubsts);
assert!(!psubsts.types.needs_infer() && !psubsts.types.has_param_types());
@ -174,7 +173,7 @@ pub struct Instance<'tcx> {
impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[], |_| None)
ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[])
}
}

View File

@ -125,6 +125,7 @@ use rustc::hir::map::DefPathData;
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
use rustc::ty::TyCtxt;
use rustc::ty::item_path::characteristic_def_id_of_type;
use rustc::ty::subst;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher, SipHasher};
use std::sync::Arc;
@ -486,7 +487,8 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// its self-type. If the self-type does not provide a characteristic
// DefId, we use the location of the impl after all.
if let Some(self_ty) = instance.substs.self_ty() {
if tcx.trait_of_item(instance.def).is_some() {
let self_ty = *instance.substs.types.get(subst::SelfSpace, 0);
// This is an implementation of a trait method.
return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
}

View File

@ -28,7 +28,7 @@ use rustc::hir;
use rustc::hir::map as hir_map;
use rustc::hir::def_id::DefId;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::subst;
use rustc::ty::subst::{Substs, VecPerParamSpace};
use rustc_const_eval::fatal_const_eval_err;
use std::hash::{Hash, Hasher};
use syntax::ast::{self, NodeId};
@ -352,8 +352,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,
tcx.mk_substs(subst::Substs::empty()));
let instance = Instance::new(def_id, Substs::empty(tcx));
to_string_internal(tcx, "static ", instance)
},
};
@ -561,7 +560,7 @@ fn push_item_name(tcx: TyCtxt,
}
fn push_type_params<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
types: &'tcx subst::VecPerParamSpace<Ty<'tcx>>,
types: &'tcx VecPerParamSpace<Ty<'tcx>>,
projections: &[ty::PolyExistentialProjection<'tcx>],
output: &mut String) {
if types.is_empty() && projections.is_empty() {

View File

@ -11,7 +11,6 @@
#![allow(non_camel_case_types)]
use rustc::hir::def_id::DefId;
use rustc::ty::subst;
use abi::FnType;
use adt;
use common::*;
@ -257,7 +256,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// avoids creating more than one copy of the enum when one
// of the enum's variants refers to the enum itself.
let repr = adt::represent_type(cx, t);
let tps = substs.types.get_slice(subst::TypeSpace);
let tps = substs.types.as_full_slice();
let name = llvm_type_name(cx, def.did, tps);
adt::incomplete_type_of(cx, &repr, &name[..])
}
@ -336,7 +335,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
// in *after* placing it into the type cache. This prevents
// infinite recursion with recursive struct types.
let repr = adt::represent_type(cx, t);
let tps = substs.types.get_slice(subst::TypeSpace);
let tps = substs.types.as_full_slice();
let name = llvm_type_name(cx, def.did, tps);
adt::incomplete_type_of(cx, &repr, &name[..])
}

View File

@ -81,6 +81,10 @@ pub trait AstConv<'gcx, 'tcx> {
/// A cache used for the result of `ast_ty_to_ty_cache`
fn ast_ty_to_ty_cache(&self) -> &RefCell<NodeMap<Ty<'tcx>>>;
/// Returns the generic type and lifetime parameters for an item.
fn get_generics(&self, span: Span, id: DefId)
-> Result<&'tcx ty::Generics<'tcx>, ErrorReported>;
/// Identify the type scheme for an item with a type, like a type
/// alias, fn, or struct. This allows you to figure out the set of
/// type parameters defined on the item.
@ -348,7 +352,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
rscope: &RegionScope,
span: Span,
param_mode: PathParamMode,
decl_generics: &ty::Generics<'tcx>,
def_id: DefId,
item_segment: &hir::PathSegment)
-> &'tcx Substs<'tcx>
{
@ -362,11 +366,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
.span_label(span, &format!("only traits may use parentheses"))
.emit();
return tcx.mk_substs(Substs::from_generics(decl_generics, |_, _| {
return Substs::for_item(tcx, def_id, |_, _| {
ty::ReStatic
}, |_, _| {
tcx.types.err
}));
});
}
}
@ -374,7 +378,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
self.create_substs_for_ast_path(rscope,
span,
param_mode,
decl_generics,
def_id,
&item_segment.parameters,
None);
@ -392,16 +396,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
rscope: &RegionScope,
span: Span,
param_mode: PathParamMode,
decl_generics: &ty::Generics<'tcx>,
def_id: DefId,
parameters: &hir::PathParameters,
self_ty: Option<Ty<'tcx>>)
-> (&'tcx Substs<'tcx>, Vec<ConvertedBinding<'tcx>>)
{
let tcx = self.tcx();
debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}, \
debug!("create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
parameters={:?})",
decl_generics, self_ty, parameters);
def_id, self_ty, parameters);
let (lifetimes, num_types_provided) = match *parameters {
hir::AngleBracketedParameters(ref data) => {
@ -417,6 +421,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
// If the type is parameterized by this region, then replace this
// region with the current anon region binding (in other words,
// whatever & would get replaced with).
let decl_generics = match self.get_generics(span, def_id) {
Ok(generics) => generics,
Err(ErrorReported) => {
// No convenient way to recover from a cycle here. Just bail. Sorry!
self.tcx().sess.abort_if_errors();
bug!("ErrorReported returned, but no errors reports?")
}
};
let expected_num_region_params = decl_generics.regions.len(TypeSpace);
let supplied_num_region_params = lifetimes.len();
let regions = if expected_num_region_params == supplied_num_region_params {
@ -438,7 +450,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
};
// If a self-type was declared, one should be provided.
assert_eq!(decl_generics.types.get_self().is_some(), self_ty.is_some());
assert_eq!(decl_generics.has_self, self_ty.is_some());
// Check the number of type parameters supplied by the user.
if let Some(num_provided) = num_types_provided {
@ -460,7 +472,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
};
let mut output_assoc_binding = None;
let substs = Substs::from_generics(decl_generics, |def, _| {
let substs = Substs::for_item(tcx, def_id, |def, _| {
assert_eq!(def.space, TypeSpace);
regions[def.index as usize]
}, |def, substs| {
@ -532,7 +544,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
vec![output_assoc_binding.unwrap_or_else(|| {
// This is an error condition, but we should
// get the associated type binding anyway.
self.convert_parenthesized_parameters(rscope, &substs, data).1
self.convert_parenthesized_parameters(rscope, substs, data).1
})]
}
};
@ -540,7 +552,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
debug!("create_substs_for_ast_path(decl_generics={:?}, self_ty={:?}) -> {:?}",
decl_generics, self_ty, substs);
(tcx.mk_substs(substs), assoc_bindings)
(substs, assoc_bindings)
}
/// Returns the appropriate lifetime to use for any output lifetimes
@ -803,7 +815,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
self.create_substs_for_ast_path(rscope,
span,
param_mode,
&trait_def.generics,
trait_def_id,
&trait_segment.parameters,
Some(self_ty))
}
@ -910,10 +922,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
-> Ty<'tcx>
{
let tcx = self.tcx();
let (generics, decl_ty) = match self.get_item_type_scheme(span, did) {
Ok(ty::TypeScheme { generics, ty: decl_ty }) => {
(generics, decl_ty)
}
let decl_ty = match self.get_item_type_scheme(span, did) {
Ok(type_scheme) => type_scheme.ty,
Err(ErrorReported) => {
return tcx.types.err;
}
@ -922,7 +932,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
let substs = self.ast_path_substs_for_ty(rscope,
span,
param_mode,
&generics,
did,
item_segment);
// FIXME(#12938): This is a hack until we have full support for DST.
@ -1682,7 +1692,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
// Create the anonymized type.
let def_id = tcx.map.local_def_id(ast_ty.id);
if let Some(anon_scope) = rscope.anon_type_scope() {
let substs = anon_scope.fresh_substs(tcx);
let substs = anon_scope.fresh_substs(self, ast_ty.span);
let ty = tcx.mk_anon(tcx.map.local_def_id(ast_ty.id), substs);
// Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.

View File

@ -547,10 +547,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
// Type check the path.
let scheme = tcx.lookup_item_type(def.def_id());
let predicates = tcx.lookup_predicates(def.def_id());
let pat_ty = self.instantiate_value_path(segments, scheme, &predicates,
opt_ty, def, pat.span, pat.id);
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
self.demand_suptype(pat.span, expected, pat_ty);
}
@ -607,18 +604,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
// Type check the path.
let scheme = tcx.lookup_item_type(def.def_id());
let scheme = if scheme.ty.is_fn() {
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
let pat_ty = if pat_ty.is_fn() {
// Replace constructor type with constructed type for tuple struct patterns.
let fn_ret = tcx.no_late_bound_regions(&scheme.ty.fn_ret()).unwrap();
ty::TypeScheme { ty: fn_ret, generics: scheme.generics }
tcx.no_late_bound_regions(&pat_ty.fn_ret()).unwrap()
} else {
// Leave the type as is for unit structs (backward compatibility).
scheme
pat_ty
};
let predicates = tcx.lookup_predicates(def.def_id());
let pat_ty = self.instantiate_value_path(segments, scheme, &predicates,
opt_ty, def, pat.span, pat.id);
self.write_ty(pat.id, pat_ty);
self.demand_eqtype(pat.span, expected, pat_ty);
// Type check subpatterns.

View File

@ -101,7 +101,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
Some(f) => f,
None => return None
},
substs: tcx.mk_substs(Substs::new_trait(vec![], vec![], self.cur_ty))
substs: Substs::new_trait(tcx, vec![], vec![], self.cur_ty)
};
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);

View File

@ -194,10 +194,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// Create mapping from trait to skolemized.
let trait_to_skol_substs =
trait_to_impl_substs
.subst(tcx, impl_to_skol_substs).clone()
.with_method(impl_to_skol_substs.types.get_slice(subst::FnSpace).to_vec(),
impl_to_skol_substs.regions.get_slice(subst::FnSpace).to_vec());
impl_to_skol_substs.rebase_onto(tcx, impl_m.container_id(),
trait_to_impl_substs.subst(tcx, impl_to_skol_substs));
debug!("compare_impl_method: trait_to_skol_substs={:?}",
trait_to_skol_substs);
@ -208,7 +206,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
impl_m,
&trait_m.generics,
&impl_m.generics,
&trait_to_skol_substs,
trait_to_skol_substs,
impl_to_skol_substs) {
return;
}
@ -226,7 +224,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let mut fulfillment_cx = traits::FulfillmentContext::new();
// Normalize the associated types in the trait_bounds.
let trait_bounds = trait_m.predicates.instantiate(tcx, &trait_to_skol_substs);
let trait_bounds = trait_m.predicates.instantiate(tcx, trait_to_skol_substs);
// Create obligations for each predicate declared by the impl
// definition in the context of the trait's parameter
@ -323,7 +321,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
infcx.parameter_environment.free_id_outlive,
&trait_m.fty.sig);
let trait_sig =
trait_sig.subst(tcx, &trait_to_skol_substs);
trait_sig.subst(tcx, trait_to_skol_substs);
let trait_sig =
assoc::normalize_associated_types_in(&infcx,
&mut fulfillment_cx,
@ -454,16 +452,14 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// Create mapping from trait to skolemized.
let trait_to_skol_substs =
trait_to_impl_substs
.subst(tcx, impl_to_skol_substs).clone()
.with_method(impl_to_skol_substs.types.get_slice(subst::FnSpace).to_vec(),
impl_to_skol_substs.regions.get_slice(subst::FnSpace).to_vec());
impl_to_skol_substs.rebase_onto(tcx, impl_c.container.id(),
trait_to_impl_substs.subst(tcx, impl_to_skol_substs));
debug!("compare_const_impl: trait_to_skol_substs={:?}",
trait_to_skol_substs);
// Compute skolemized form of impl and trait const tys.
let impl_ty = impl_c.ty.subst(tcx, impl_to_skol_substs);
let trait_ty = trait_c.ty.subst(tcx, &trait_to_skol_substs);
let trait_ty = trait_c.ty.subst(tcx, trait_to_skol_substs);
let mut origin = TypeOrigin::Misc(impl_c_span);
let err = infcx.commit_if_ok(|_| {

View File

@ -15,7 +15,7 @@ use hir::def_id::DefId;
use middle::free_region::FreeRegionMap;
use rustc::infer;
use middle::region;
use rustc::ty::subst::{self, Subst};
use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::traits::{self, Reveal};
use util::nodemap::FnvHashSet;
@ -41,16 +41,14 @@ use syntax_pos::{self, Span};
/// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
///
pub fn check_drop_impl(ccx: &CrateCtxt, drop_impl_did: DefId) -> Result<(), ()> {
let ty::TypeScheme { generics: ref dtor_generics,
ty: dtor_self_type } = ccx.tcx.lookup_item_type(drop_impl_did);
let dtor_self_type = ccx.tcx.lookup_item_type(drop_impl_did).ty;
let dtor_predicates = ccx.tcx.lookup_predicates(drop_impl_did);
match dtor_self_type.sty {
ty::TyEnum(adt_def, self_to_impl_substs) |
ty::TyStruct(adt_def, self_to_impl_substs) => {
ensure_drop_params_and_item_params_correspond(ccx,
drop_impl_did,
dtor_generics,
&dtor_self_type,
dtor_self_type,
adt_def.did)?;
ensure_drop_predicates_are_implied_by_item_defn(ccx,
@ -73,8 +71,7 @@ pub fn check_drop_impl(ccx: &CrateCtxt, drop_impl_did: DefId) -> Result<(), ()>
fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
ccx: &CrateCtxt<'a, 'tcx>,
drop_impl_did: DefId,
drop_impl_generics: &ty::Generics<'tcx>,
drop_impl_ty: &ty::Ty<'tcx>,
drop_impl_ty: Ty<'tcx>,
self_type_did: DefId) -> Result<(), ()>
{
let tcx = ccx.tcx;
@ -93,8 +90,8 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
let drop_impl_span = tcx.map.def_id_span(drop_impl_did, syntax_pos::DUMMY_SP);
let fresh_impl_substs =
infcx.fresh_substs_for_generics(drop_impl_span, drop_impl_generics);
let fresh_impl_self_ty = drop_impl_ty.subst(tcx, &fresh_impl_substs);
infcx.fresh_substs_for_item(drop_impl_span, drop_impl_did);
let fresh_impl_self_ty = drop_impl_ty.subst(tcx, fresh_impl_substs);
if let Err(_) = infcx.eq_types(true, infer::TypeOrigin::Misc(drop_impl_span),
named_type, fresh_impl_self_ty) {
@ -131,7 +128,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
drop_impl_did: DefId,
dtor_predicates: &ty::GenericPredicates<'tcx>,
self_type_did: DefId,
self_to_impl_substs: &subst::Substs<'tcx>) -> Result<(), ()> {
self_to_impl_substs: &Substs<'tcx>) -> Result<(), ()> {
// Here is an example, analogous to that from
// `compare_impl_method`.

View File

@ -36,11 +36,11 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let def_id = tcx.map.local_def_id(it.id);
let i_ty = tcx.lookup_item_type(def_id);
let mut substs = Substs::empty();
substs.types = i_ty.generics.types.map(|def| tcx.mk_param_from_def(def));
let substs = Substs::for_item(tcx, def_id,
|_, _| ty::ReErased,
|def, _| tcx.mk_param_from_def(def));
let fty = tcx.mk_fn_def(def_id, tcx.mk_substs(substs),
tcx.mk_bare_fn(ty::BareFnTy {
let fty = tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Unsafe,
abi: abi,
sig: ty::Binder(FnSig {

View File

@ -12,7 +12,7 @@ use super::probe;
use check::{FnCtxt, callee};
use hir::def_id::DefId;
use rustc::ty::subst::{self};
use rustc::ty::subst::{self, Substs};
use rustc::traits;
use rustc::ty::{self, LvaluePreference, NoPreference, PreferMutLvalue, Ty};
use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr};
@ -42,10 +42,6 @@ struct InstantiatedMethodSig<'tcx> {
/// argument is the receiver.
method_sig: ty::FnSig<'tcx>,
/// Substitutions for all types/early-bound-regions declared on
/// the method.
all_substs: subst::Substs<'tcx>,
/// Generic bounds on the method's parameters which must be added
/// as pending obligations.
method_predicates: ty::InstantiatedPredicates<'tcx>,
@ -105,9 +101,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// Create the final signature for the method, replacing late-bound regions.
let InstantiatedMethodSig {
method_sig, all_substs, method_predicates
method_sig, method_predicates
} = self.instantiate_method_sig(&pick, all_substs);
let all_substs = self.tcx.mk_substs(all_substs);
let method_self_ty = method_sig.inputs[0];
// Unify the (adjusted) self type with what the method expects.
@ -198,7 +193,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
fn fresh_receiver_substs(&mut self,
self_ty: Ty<'tcx>,
pick: &probe::Pick<'tcx>)
-> &'tcx subst::Substs<'tcx>
-> &'tcx Substs<'tcx>
{
match pick.kind {
probe::InherentImplPick => {
@ -256,16 +251,13 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
probe::TraitPick => {
let trait_def_id = pick.item.container().id();
let trait_def = self.tcx.lookup_trait_def(trait_def_id);
// Make a trait reference `$0 : Trait<$1...$n>`
// consisting entirely of type variables. Later on in
// the process we will unify the transformed-self-type
// of the method with the actual type in order to
// unify some of these variables.
self.fresh_substs_for_trait(self.span,
&trait_def.generics,
self.next_ty_var())
self.fresh_substs_for_item(self.span, trait_def_id)
}
probe::WhereClausePick(ref poly_trait_ref) => {
@ -308,8 +300,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
fn instantiate_method_substs(&mut self,
pick: &probe::Pick<'tcx>,
mut supplied_method_types: Vec<Ty<'tcx>>,
substs: &subst::Substs<'tcx>)
-> subst::Substs<'tcx>
substs: &Substs<'tcx>)
-> &'tcx Substs<'tcx>
{
// Determine the values for the generic parameters of the method.
// If they were not explicitly supplied, just construct fresh
@ -335,7 +327,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// parameters from the type and those from the method.
//
// FIXME -- permit users to manually specify lifetimes
subst::Substs::from_generics(&method.generics, |def, _| {
Substs::for_item(self.tcx, method.def_id, |def, _| {
if def.space != subst::FnSpace {
substs.region_for_def(def)
} else {
@ -376,7 +368,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
fn instantiate_method_sig(&mut self,
pick: &probe::Pick<'tcx>,
all_substs: subst::Substs<'tcx>)
all_substs: &'tcx Substs<'tcx>)
-> InstantiatedMethodSig<'tcx>
{
debug!("instantiate_method_sig(pick={:?}, all_substs={:?})",
@ -387,7 +379,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// type/early-bound-regions substitutions performed. There can
// be no late-bound regions appearing here.
let method_predicates = pick.item.as_opt_method().unwrap()
.predicates.instantiate(self.tcx, &all_substs);
.predicates.instantiate(self.tcx, all_substs);
let method_predicates = self.normalize_associated_types_in(self.span,
&method_predicates);
@ -405,20 +397,19 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
debug!("late-bound lifetimes from method instantiated, method_sig={:?}",
method_sig);
let method_sig = self.instantiate_type_scheme(self.span, &all_substs, &method_sig);
let method_sig = self.instantiate_type_scheme(self.span, all_substs, &method_sig);
debug!("type scheme substituted, method_sig={:?}",
method_sig);
InstantiatedMethodSig {
method_sig: method_sig,
all_substs: all_substs,
method_predicates: method_predicates,
}
}
fn add_obligations(&mut self,
fty: Ty<'tcx>,
all_substs: &subst::Substs<'tcx>,
all_substs: &Substs<'tcx>,
method_predicates: &ty::InstantiatedPredicates<'tcx>) {
debug!("add_obligations: fty={:?} all_substs={:?} method_predicates={:?}",
fty,

View File

@ -13,7 +13,7 @@
use check::FnCtxt;
use hir::def::Def;
use hir::def_id::DefId;
use rustc::ty::subst;
use rustc::ty::subst::{self, Substs};
use rustc::traits;
use rustc::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr};
@ -189,7 +189,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
assert!(trait_def.generics.regions.is_empty());
// Construct a trait-reference `self_ty : Trait<input_tys>`
let substs = subst::Substs::from_generics(&trait_def.generics, |def, _| {
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
self.region_var_for_def(span, def)
}, |def, substs| {
if def.space == subst::SelfSpace {
@ -201,7 +201,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
});
let trait_ref = ty::TraitRef::new(trait_def_id, self.tcx.mk_substs(substs));
let trait_ref = ty::TraitRef::new(trait_def_id, substs);
// Construct an obligation
let poly_trait_ref = trait_ref.to_poly_trait_ref();

View File

@ -16,8 +16,7 @@ use super::suggest;
use check::{FnCtxt};
use hir::def_id::DefId;
use hir::def::Def;
use rustc::ty::subst;
use rustc::ty::subst::Subst;
use rustc::ty::subst::{self, Subst, Substs};
use rustc::traits;
use rustc::ty::{self, Ty, ToPolyTraitRef, TraitRef, TypeFoldable};
use rustc::infer::{InferOk, TypeOrigin};
@ -80,9 +79,9 @@ struct Candidate<'tcx> {
#[derive(Debug)]
enum CandidateKind<'tcx> {
InherentImplCandidate(subst::Substs<'tcx>,
InherentImplCandidate(&'tcx Substs<'tcx>,
/* Normalize obligations */ Vec<traits::PredicateObligation<'tcx>>),
ExtensionImplCandidate(/* Impl */ DefId, subst::Substs<'tcx>,
ExtensionImplCandidate(/* Impl */ DefId, &'tcx Substs<'tcx>,
/* Normalize obligations */ Vec<traits::PredicateObligation<'tcx>>),
ObjectCandidate,
TraitCandidate,
@ -421,10 +420,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
}
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
let impl_ty = impl_ty.subst(self.tcx, &impl_substs);
let impl_ty = impl_ty.subst(self.tcx, impl_substs);
// Determine the receiver type that the method itself expects.
let xform_self_ty = self.xform_self_ty(&item, impl_ty, &impl_substs);
let xform_self_ty = self.xform_self_ty(&item, impl_ty, impl_substs);
// We can't use normalize_associated_types_in as it will pollute the
// fcx's fulfillment context after this probe is over.
@ -519,14 +518,14 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
trait_ref,
trait_ref.substs,
m);
assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
trait_ref.substs.types.get_slice(subst::TypeSpace).len());
assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
trait_ref.substs.regions.get_slice(subst::TypeSpace).len());
assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
trait_ref.substs.types.get_slice(subst::SelfSpace).len());
assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
trait_ref.substs.regions.get_slice(subst::SelfSpace).len());
assert_eq!(m.generics.types.len(subst::TypeSpace),
trait_ref.substs.types.len(subst::TypeSpace));
assert_eq!(m.generics.regions.len(subst::TypeSpace),
trait_ref.substs.regions.len(subst::TypeSpace));
assert_eq!(m.generics.types.len(subst::SelfSpace),
trait_ref.substs.types.len(subst::SelfSpace));
assert_eq!(m.generics.regions.len(subst::SelfSpace),
trait_ref.substs.regions.len(subst::SelfSpace));
}
// Because this trait derives from a where-clause, it
@ -665,7 +664,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
let impl_trait_ref =
self.tcx.impl_trait_ref(impl_def_id)
.unwrap() // we know this is a trait impl
.subst(self.tcx, &impl_substs);
.subst(self.tcx, impl_substs);
debug!("impl_trait_ref={:?}", impl_trait_ref);
@ -753,14 +752,21 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
// for the purposes of our method lookup, we only take
// receiver type into account, so we can just substitute
// fresh types here to use during substitution and subtyping.
let trait_def = self.tcx.lookup_trait_def(trait_def_id);
let substs = self.fresh_substs_for_trait(self.span,
&trait_def.generics,
step.self_ty);
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
self.region_var_for_def(self.span, def)
}, |def, substs| {
if def.space == subst::SelfSpace {
assert_eq!(def.index, 0);
step.self_ty
} else {
assert_eq!(def.space, subst::TypeSpace);
self.type_var_for_def(self.span, def, substs)
}
});
let xform_self_ty = self.xform_self_ty(&item,
step.self_ty,
&substs);
substs);
self.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
item: item.clone(),
@ -1192,7 +1198,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
fn xform_self_ty(&self,
item: &ty::ImplOrTraitItem<'tcx>,
impl_ty: Ty<'tcx>,
substs: &subst::Substs<'tcx>)
substs: &Substs<'tcx>)
-> Ty<'tcx>
{
match item.as_opt_method() {
@ -1205,7 +1211,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
fn xform_method_self_ty(&self,
method: &Rc<ty::Method<'tcx>>,
impl_ty: Ty<'tcx>,
substs: &subst::Substs<'tcx>)
substs: &Substs<'tcx>)
-> Ty<'tcx>
{
debug!("xform_self_ty(impl_ty={:?}, self_ty={:?}, substs={:?})",
@ -1236,7 +1242,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
method.generics.regions.is_empty_in(subst::FnSpace) {
xform_self_ty.subst(self.tcx, substs)
} else {
let substs = subst::Substs::from_generics(&method.generics, |def, _| {
let substs = Substs::for_item(self.tcx, method.def_id, |def, _| {
if def.space != subst::FnSpace {
substs.region_for_def(def)
} else {
@ -1251,14 +1257,14 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
self.type_var_for_def(self.span, def, cur_substs)
}
});
xform_self_ty.subst(self.tcx, &substs)
xform_self_ty.subst(self.tcx, substs)
}
}
/// Get the type of an impl and generate substitutions with placeholders.
fn impl_ty_and_substs(&self,
impl_def_id: DefId)
-> (Ty<'tcx>, subst::Substs<'tcx>)
-> (Ty<'tcx>, &'tcx Substs<'tcx>)
{
let impl_pty = self.tcx.lookup_item_type(impl_def_id);
@ -1270,8 +1276,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
impl_pty.generics.regions.map(
|_| ty::ReErased); // see erase_late_bound_regions() for an expl of why 'erased
let substs = subst::Substs::new(type_vars, region_placeholders);
(impl_pty.ty, substs)
(impl_pty.ty, Substs::new(self.tcx, type_vars, region_placeholders))
}
/// Replace late-bound-regions bound by `value` with `'static` using

View File

@ -54,10 +54,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.autoderef(span, ty).any(|(ty, _)| self.probe(|_| {
let fn_once_substs =
Substs::new_trait(vec![self.next_ty_var()], vec![], ty);
let trait_ref =
ty::TraitRef::new(fn_once,
tcx.mk_substs(fn_once_substs));
Substs::new_trait(tcx, vec![self.next_ty_var()], vec![], ty);
let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
let poly_trait_ref = trait_ref.to_poly_trait_ref();
let obligation = Obligation::misc(span,
self.body_id,

View File

@ -90,7 +90,6 @@ use hir::pat_util;
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
use rustc::ty::subst::{self, Subst, Substs};
use rustc::traits::{self, Reveal};
use rustc::ty::{GenericPredicates, TypeScheme};
use rustc::ty::{ParamTy, ParameterEnvironment};
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, Visibility};
@ -745,26 +744,20 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
let impl_def_id = ccx.tcx.map.local_def_id(it.id);
match ccx.tcx.impl_trait_ref(impl_def_id) {
Some(impl_trait_ref) => {
let trait_def_id = impl_trait_ref.def_id;
check_impl_items_against_trait(ccx,
it.span,
impl_def_id,
&impl_trait_ref,
impl_items);
check_on_unimplemented(
ccx,
&ccx.tcx.lookup_trait_def(trait_def_id).generics,
it,
ccx.tcx.item_name(trait_def_id));
let trait_def_id = impl_trait_ref.def_id;
check_on_unimplemented(ccx, trait_def_id, it);
}
None => { }
}
}
hir::ItemTrait(..) => {
let def_id = ccx.tcx.map.local_def_id(it.id);
let generics = &ccx.tcx.lookup_trait_def(def_id).generics;
check_on_unimplemented(ccx, generics, it, it.name);
check_on_unimplemented(ccx, def_id, it);
}
hir::ItemStruct(..) => {
check_struct(ccx, it.id, it.span);
@ -872,9 +865,9 @@ fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
generics: &ty::Generics,
item: &hir::Item,
name: ast::Name) {
def_id: DefId,
item: &hir::Item) {
let generics = ccx.tcx.lookup_generics(def_id);
if let Some(ref attr) = item.attrs.iter().find(|a| {
a.check_name("rustc_on_unimplemented")
}) {
@ -894,6 +887,7 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}) {
Some(_) => (),
None => {
let name = ccx.tcx.item_name(def_id);
span_err!(ccx.tcx.sess, attr.span, E0230,
"there is no type parameter \
{} on trait {}",
@ -1301,6 +1295,12 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
&self.ast_ty_to_ty_cache
}
fn get_generics(&self, _: Span, id: DefId)
-> Result<&'tcx ty::Generics<'tcx>, ErrorReported>
{
Ok(self.tcx().lookup_generics(id))
}
fn get_item_type_scheme(&self, _: Span, id: DefId)
-> Result<ty::TypeScheme<'tcx>, ErrorReported>
{
@ -1364,7 +1364,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
fn ty_infer_for_def(&self,
ty_param_def: &ty::TypeParameterDef<'tcx>,
substs: &subst::Substs<'tcx>,
substs: &Substs<'tcx>,
span: Span) -> Ty<'tcx> {
self.type_var_for_def(span, ty_param_def, substs)
}
@ -1690,25 +1690,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
node_id: ast::NodeId)
-> Ty<'tcx> {
debug!("instantiate_type_path(did={:?}, path={:?})", did, path);
let mut type_scheme = self.tcx.lookup_item_type(did);
if type_scheme.ty.is_fn() {
let mut ty = self.tcx.lookup_item_type(did).ty;
if ty.is_fn() {
// Tuple variants have fn type even in type namespace, extract true variant type from it
let fn_ret = self.tcx.no_late_bound_regions(&type_scheme.ty.fn_ret()).unwrap();
type_scheme = ty::TypeScheme { ty: fn_ret, generics: type_scheme.generics }
ty = self.tcx.no_late_bound_regions(&type_scheme.ty.fn_ret()).unwrap();
}
let type_predicates = self.tcx.lookup_predicates(did);
let substs = AstConv::ast_path_substs_for_ty(self, self,
path.span,
PathParamMode::Optional,
&type_scheme.generics,
did,
path.segments.last().unwrap());
debug!("instantiate_type_path: ty={:?} substs={:?}", &type_scheme.ty, substs);
debug!("instantiate_type_path: ty={:?} substs={:?}", ty, substs);
let bounds = self.instantiate_bounds(path.span, substs, &type_predicates);
let cause = traits::ObligationCause::new(path.span, self.body_id,
traits::ItemObligation(did));
self.add_obligations_for_parameters(cause, &bounds);
let ty_substituted = self.instantiate_type_scheme(path.span, substs, &type_scheme.ty);
let ty_substituted = self.instantiate_type_scheme(path.span, substs, &ty);
self.write_ty(node_id, ty_substituted);
self.write_substs(node_id, ty::ItemSubsts {
substs: substs
@ -2775,7 +2774,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let ity = self.tcx.lookup_item_type(did);
debug!("impl_self_ty: ity={:?}", ity);
let substs = self.fresh_substs_for_generics(span, &ity.generics);
let substs = self.fresh_substs_for_item(span, did);
let substd_ty = self.instantiate_type_scheme(span, &substs, &ity.ty);
TypeAndSubsts { substs: substs, ty: substd_ty }
@ -3443,10 +3442,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(opt_self_ty, path,
expr.id, expr.span);
if def != Def::Err {
let (scheme, predicates) = self.type_scheme_and_predicates_for_def(expr.span,
def);
self.instantiate_value_path(segments, scheme, &predicates,
opt_ty, def, expr.span, id);
self.instantiate_value_path(segments, opt_ty, def, expr.span, id);
} else {
self.set_tainted_by_errors();
self.write_error(id);
@ -4036,54 +4032,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
*self.ps.borrow_mut() = prev;
}
// Returns the type parameter count and the type for the given definition.
fn type_scheme_and_predicates_for_def(&self,
sp: Span,
defn: Def)
-> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
match defn {
Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
let typ = self.local_ty(sp, nid);
(ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
ty::GenericPredicates::empty())
}
Def::Fn(id) | Def::Method(id) |
Def::Static(id, _) | Def::Variant(_, id) |
Def::Struct(id) | Def::Const(id) | Def::AssociatedConst(id) => {
(self.tcx.lookup_item_type(id), self.tcx.lookup_predicates(id))
}
Def::Trait(_) |
Def::Enum(..) |
Def::TyAlias(..) |
Def::AssociatedTy(..) |
Def::PrimTy(_) |
Def::TyParam(..) |
Def::Mod(..) |
Def::ForeignMod(..) |
Def::Label(..) |
Def::SelfTy(..) |
Def::Err => {
span_bug!(sp, "expected value, found {:?}", defn);
}
}
}
// Instantiates the given path, which must refer to an item with the given
// number of type parameters and type.
pub fn instantiate_value_path(&self,
segments: &[hir::PathSegment],
type_scheme: TypeScheme<'tcx>,
type_predicates: &ty::GenericPredicates<'tcx>,
opt_self_ty: Option<Ty<'tcx>>,
def: Def,
span: Span,
node_id: ast::NodeId)
-> Ty<'tcx> {
debug!("instantiate_value_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})",
debug!("instantiate_value_path(path={:?}, def={:?}, node_id={})",
segments,
def,
node_id,
type_scheme);
node_id);
// We need to extract the type parameters supplied by the user in
// the path `path`. Due to the current setup, this is a bit of a
@ -4210,11 +4171,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Def::ForeignMod(..) |
Def::Local(..) |
Def::Label(..) |
Def::Upvar(..) => {}
Def::Err => {
self.set_tainted_by_errors();
}
Def::Upvar(..) |
Def::Err => {}
}
// In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
@ -4232,6 +4190,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn_segment.is_some() as usize;
self.tcx.prohibit_type_params(&segments[..segments.len() - poly_segments]);
match def {
Def::Local(_, nid) | Def::Upvar(_, nid, _, _) => {
let ty = self.local_ty(span, nid);
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)
});
return ty;
}
_ => {}
}
let scheme = self.tcx.lookup_item_type(def.def_id());
let type_predicates = self.tcx.lookup_predicates(def.def_id());
// Now we have to compare the types that the user *actually*
// provided against the types that were *expected*. If the user
// did not provide any types, then we want to substitute inference
@ -4240,16 +4213,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// a problem.
self.check_path_parameter_count(subst::TypeSpace,
span,
&type_scheme.generics,
scheme.generics,
!require_type_space,
&mut type_segment);
self.check_path_parameter_count(subst::FnSpace,
span,
&type_scheme.generics,
scheme.generics,
true,
&mut fn_segment);
let substs = Substs::from_generics(&type_scheme.generics, |def, _| {
let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
let i = def.index as usize;
let segment = match def.space {
subst::SelfSpace => None,
@ -4307,9 +4280,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// The things we are substituting into the type should not contain
// escaping late-bound regions, and nor should the base type scheme.
let substs = self.tcx.mk_substs(substs);
assert!(!substs.has_escaping_regions());
assert!(!type_scheme.has_escaping_regions());
assert!(!scheme.ty.has_escaping_regions());
// Add all the obligations that are required, substituting and
// normalized appropriately.
@ -4320,7 +4292,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Substitute the values for the type parameters into the type of
// the referenced item.
let ty_substituted = self.instantiate_type_scheme(span, &substs, &type_scheme.ty);
let ty_substituted = self.instantiate_type_scheme(span, &substs, &scheme.ty);
if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {

View File

@ -18,7 +18,6 @@ use hir::def_id::DefId;
use rustc::ty::{self, Ty, TyCtxt, MethodCall, MethodCallee};
use rustc::ty::adjustment;
use rustc::ty::fold::{TypeFolder,TypeFoldable};
use rustc::ty::subst::ParamSpace;
use rustc::infer::{InferCtxt, FixupError};
use rustc::util::nodemap::DefIdMap;
use write_substs_to_tcx;
@ -68,7 +67,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
wbcx.visit_closures();
wbcx.visit_liberated_fn_sigs();
wbcx.visit_fru_field_types();
wbcx.visit_anon_types();
wbcx.visit_anon_types(item_id);
wbcx.visit_deferred_obligations(item_id);
}
}
@ -104,22 +103,20 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
let free_substs = fcx.parameter_environment.free_substs;
for &space in &ParamSpace::all() {
for (i, r) in free_substs.regions.get_slice(space).iter().enumerate() {
match *r {
ty::ReFree(ty::FreeRegion {
bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
}) => {
let bound_region = ty::ReEarlyBound(ty::EarlyBoundRegion {
space: space,
index: i as u32,
name: name,
});
wbcx.free_to_bound_regions.insert(def_id, bound_region);
}
_ => {
bug!("{:?} is not a free region for an early-bound lifetime", r);
}
for (space, i, r) in free_substs.regions.iter_enumerated() {
match *r {
ty::ReFree(ty::FreeRegion {
bound_region: ty::BoundRegion::BrNamed(def_id, name, _), ..
}) => {
let bound_region = ty::ReEarlyBound(ty::EarlyBoundRegion {
space: space,
index: i as u32,
name: name,
});
wbcx.free_to_bound_regions.insert(def_id, bound_region);
}
_ => {
bug!("{:?} is not a free region for an early-bound lifetime", r);
}
}
}
@ -300,11 +297,13 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
}
fn visit_anon_types(&self) {
fn visit_anon_types(&self, item_id: ast::NodeId) {
if self.fcx.writeback_errors.get() {
return
}
let item_def_id = self.fcx.tcx.map.local_def_id(item_id);
let gcx = self.tcx().global_tcx();
for (&def_id, &concrete_ty) in self.fcx.anon_types.borrow().iter() {
let reason = ResolvingAnonTy(def_id);
@ -345,9 +344,9 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
});
gcx.tcache.borrow_mut().insert(def_id, ty::TypeScheme {
gcx.register_item_type(def_id, ty::TypeScheme {
ty: outside_ty,
generics: ty::Generics::empty()
generics: gcx.lookup_generics(item_def_id)
});
}
}

View File

@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem;
use middle::const_val::ConstVal;
use rustc_const_eval::EvalHint::UncheckedExprHint;
use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace};
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
use rustc::ty::{VariantKind};
@ -120,6 +120,7 @@ struct ItemCtxt<'a,'tcx:'a> {
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum AstConvRequest {
GetGenerics(DefId),
GetItemTypeScheme(DefId),
GetTraitDef(DefId),
EnsureSuperPredicates(DefId),
@ -187,6 +188,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
err.span_label(span, &format!("cyclic reference"));
match cycle[0] {
AstConvRequest::GetGenerics(def_id) |
AstConvRequest::GetItemTypeScheme(def_id) |
AstConvRequest::GetTraitDef(def_id) => {
err.note(
@ -209,6 +211,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
for request in &cycle[1..] {
match *request {
AstConvRequest::GetGenerics(def_id) |
AstConvRequest::GetItemTypeScheme(def_id) |
AstConvRequest::GetTraitDef(def_id) => {
err.note(
@ -231,6 +234,7 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
}
match cycle[0] {
AstConvRequest::GetGenerics(def_id) |
AstConvRequest::GetItemTypeScheme(def_id) |
AstConvRequest::GetTraitDef(def_id) => {
err.note(
@ -303,6 +307,14 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
&self.ccx.ast_ty_to_ty_cache
}
fn get_generics(&self, span: Span, id: DefId)
-> Result<&'tcx ty::Generics<'tcx>, ErrorReported>
{
self.ccx.cycle_check(span, AstConvRequest::GetGenerics(id), || {
Ok(generics_of_def_id(self.ccx, id))
})
}
fn get_item_type_scheme(&self, span: Span, id: DefId)
-> Result<ty::TypeScheme<'tcx>, ErrorReported>
{
@ -544,7 +556,6 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
container: ImplOrTraitItemContainer,
name: ast::Name,
@ -553,25 +564,22 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
sig: &hir::MethodSig,
defaultness: hir::Defaultness,
untransformed_rcvr_ty: Ty<'tcx>,
rcvr_ty_generics: &ty::Generics<'tcx>,
rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) {
let ty_generics = ty_generics_for_fn(ccx, &sig.generics, rcvr_ty_generics);
let def_id = ccx.tcx.map.local_def_id(id);
let ty_generics = generics_of_def_id(ccx, def_id);
let ty_generic_predicates =
ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
let (fty, explicit_self_category) = {
let anon_scope = match container {
ImplContainer(_) => Some(AnonTypeScope::new(&ty_generics)),
ImplContainer(_) => Some(AnonTypeScope::new(def_id)),
TraitContainer(_) => None
};
AstConv::ty_of_method(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
sig, untransformed_rcvr_ty, anon_scope)
};
let def_id = ccx.tcx.map.local_def_id(id);
let substs = mk_item_substs(ccx.tcx, &ty_generics);
let ty_method = ty::Method::new(name,
ty_generics,
ty_generic_predicates,
@ -582,16 +590,14 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
def_id,
container);
let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)),
ccx.tcx.map.span(id), def_id);
let fty = ccx.tcx.mk_fn_def(def_id, substs, ty_method.fty);
debug!("method {} (id {}) has type {:?}",
name, id, fty);
ccx.tcx.register_item_type(def_id, TypeScheme {
generics: ty_method.generics.clone(),
ty: fty
});
ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
ccx.tcx.tcache.borrow_mut().insert(def_id, fty);
write_ty_to_tcx(ccx, id, fty);
ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
debug!("writing method type: def_id={:?} mty={:?}",
def_id, ty_method);
@ -601,7 +607,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
struct_generics: &ty::Generics<'tcx>,
struct_generics: &'tcx ty::Generics<'tcx>,
struct_predicates: &ty::GenericPredicates<'tcx>,
field: &hir::StructField,
ty_f: ty::FieldDefMaster<'tcx>)
@ -613,7 +619,7 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
/* add the field to the tcache */
ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(field.id),
ty::TypeScheme {
generics: struct_generics.clone(),
generics: struct_generics,
ty: tt
});
ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(field.id),
@ -709,8 +715,9 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
}
}
hir::ItemEnum(ref enum_definition, _) => {
let (scheme, predicates) = convert_typed_item(ccx, it);
write_ty_to_tcx(ccx, it.id, scheme.ty);
let def_id = ccx.tcx.map.local_def_id(it.id);
let scheme = type_scheme_of_def_id(ccx, def_id);
let predicates = predicates_of_item(ccx, it);
convert_enum_variant_types(ccx,
tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
scheme,
@ -737,7 +744,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
// Create generics from the generics specified in the impl head.
debug!("convert: ast_generics={:?}", generics);
let def_id = ccx.tcx.map.local_def_id(it.id);
let ty_generics = ty_generics_for_impl(ccx, generics);
let ty_generics = generics_of_def_id(ccx, def_id);
let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
debug!("convert: impl_bounds={:?}", ty_predicates);
@ -746,7 +753,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
write_ty_to_tcx(ccx, it.id, selfty);
tcx.register_item_type(def_id,
TypeScheme { generics: ty_generics.clone(),
TypeScheme { generics: ty_generics,
ty: selfty });
let trait_ref = opt_trait_ref.as_ref().map(|ast_trait_ref| {
AstConv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
@ -791,7 +798,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
.to_ty(&ExplicitRscope, &ty);
tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
TypeScheme {
generics: ty_generics.clone(),
generics: ty_generics,
ty: ty,
});
// Trait-associated constants are always public.
@ -829,7 +836,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
convert_method(ccx, ImplContainer(def_id),
impl_item.name, impl_item.id, method_vis,
sig, impl_item.defaultness, selfty, &ty_generics,
sig, impl_item.defaultness, selfty,
&ty_predicates);
}
}
@ -856,7 +863,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
.to_ty(&ExplicitRscope, ty);
tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
TypeScheme {
generics: trait_def.generics.clone(),
generics: trait_def.generics,
ty: ty,
});
convert_associated_const(ccx,
@ -898,7 +905,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
sig,
hir::Defaultness::Default,
tcx.mk_self_type(),
&trait_def.generics,
&trait_predicates);
}
@ -917,11 +923,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
trait_item_def_ids);
},
hir::ItemStruct(ref struct_def, _) => {
let (scheme, predicates) = convert_typed_item(ccx, it);
write_ty_to_tcx(ccx, it.id, scheme.ty);
let def_id = ccx.tcx.map.local_def_id(it.id);
let scheme = type_scheme_of_def_id(ccx, def_id);
let predicates = predicates_of_item(ccx, it);
let it_def_id = ccx.tcx.map.local_def_id(it.id);
let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
let variant = tcx.lookup_adt_def_master(def_id).struct_variant();
for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
convert_field(ccx, &scheme.generics, &predicates, f, ty_f)
@ -933,15 +939,14 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
},
hir::ItemTy(_, ref generics) => {
ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
let (scheme, _) = convert_typed_item(ccx, it);
write_ty_to_tcx(ccx, it.id, scheme.ty);
let def_id = ccx.tcx.map.local_def_id(it.id);
type_scheme_of_def_id(ccx, def_id);
predicates_of_item(ccx, it);
},
_ => {
// This call populates the type cache with the converted type
// of the item in passing. All we have to do here is to write
// it into the node type table.
let (scheme, _) = convert_typed_item(ccx, it);
write_ty_to_tcx(ccx, it.id, scheme.ty);
let def_id = ccx.tcx.map.local_def_id(it.id);
type_scheme_of_def_id(ccx, def_id);
predicates_of_item(ccx, it);
},
}
}
@ -952,6 +957,8 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
scheme: ty::TypeScheme<'tcx>,
predicates: ty::GenericPredicates<'tcx>) {
let tcx = ccx.tcx;
let def_id = tcx.map.local_def_id(ctor_id);
tcx.generics.borrow_mut().insert(def_id, scheme.generics);
let ctor_ty = match variant.kind {
VariantKind::Unit | VariantKind::Struct => scheme.ty,
VariantKind::Tuple => {
@ -960,8 +967,8 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
.iter()
.map(|field| field.unsubst_ty())
.collect();
let def_id = tcx.map.local_def_id(ctor_id);
let substs = mk_item_substs(tcx, &scheme.generics);
let substs = mk_item_substs(&ccx.icx(&predicates),
ccx.tcx.map.span(ctor_id), def_id);
tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy {
unsafety: hir::Unsafety::Normal,
abi: abi::Abi::Rust,
@ -974,12 +981,8 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
};
write_ty_to_tcx(ccx, ctor_id, ctor_ty);
tcx.tcache.borrow_mut().insert(def_id, ctor_ty);
tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
tcx.register_item_type(tcx.map.local_def_id(ctor_id),
TypeScheme {
generics: scheme.generics,
ty: ctor_ty
});
}
fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@ -1237,7 +1240,9 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
let (unsafety, generics, items) = match it.node {
hir::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
hir::ItemTrait(unsafety, ref generics, _, ref items) => {
(unsafety, generics, items)
}
_ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
};
@ -1253,9 +1258,8 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
err.emit();
}
let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
let ty_generics = generics_of_def_id(ccx, def_id);
let substs = mk_item_substs(&ccx.icx(generics), it.span, def_id);
let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| {
match trait_item.node {
@ -1264,51 +1268,14 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
}).collect();
let trait_ref = ty::TraitRef {
def_id: def_id,
substs: substs,
};
let trait_ref = ty::TraitRef::new(def_id, substs);
let trait_def = ty::TraitDef::new(unsafety,
paren_sugar,
ty_generics,
trait_ref,
associated_type_names);
return tcx.intern_trait_def(trait_def);
fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
generics: &hir::Generics)
-> Substs<'tcx>
{
let tcx = ccx.tcx;
// Creates a no-op substitution for the trait's type parameters.
let regions =
generics.lifetimes
.iter()
.enumerate()
.map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
space: TypeSpace,
index: i as u32,
name: def.lifetime.name
}))
.collect();
// Start with the generics in the type parameters...
let types: Vec<_> =
generics.ty_params
.iter()
.enumerate()
.map(|(i, def)| tcx.mk_param(TypeSpace,
i as u32, def.name))
.collect();
// ...and also create the `Self` parameter.
let self_ty = tcx.mk_self_type();
Substs::new_trait(types, regions, self_ty)
}
tcx.intern_trait_def(trait_def)
}
fn trait_defines_associated_type_named(ccx: &CrateCtxt,
@ -1410,105 +1377,243 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
}
}
fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
def_id: DefId)
-> ty::TypeScheme<'tcx>
{
if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
match ccx.tcx.map.find(node_id) {
Some(hir_map::NodeItem(item)) => {
type_scheme_of_item(ccx, &item)
fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
def_id: DefId)
-> &'tcx ty::Generics<'tcx> {
let tcx = ccx.tcx;
let node_id = if let Some(id) = tcx.map.as_local_node_id(def_id) {
id
} else {
return tcx.lookup_generics(def_id);
};
tcx.generics.memoize(def_id, || {
use rustc::hir::map::*;
use rustc::hir::*;
let mut opt_self = None;
let mut base_def_id = None;
let mut allow_defaults = false;
let no_generics = hir::Generics::empty();
let (space, ast_generics) = match tcx.map.get(node_id) {
NodeImplItem(&ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) |
NodeTraitItem(&TraitItem { node: MethodTraitItem(ref sig, _), .. }) => {
let parent_id = tcx.map.get_parent(node_id);
base_def_id = Some(tcx.map.local_def_id(parent_id));
(FnSpace, &sig.generics)
}
Some(hir_map::NodeForeignItem(foreign_item)) => {
NodeImplItem(_) |
NodeTraitItem(_) => {
let parent_id = tcx.map.get_parent(node_id);
base_def_id = Some(tcx.map.local_def_id(parent_id));
(FnSpace, &no_generics)
}
NodeItem(item) => {
match item.node {
ItemFn(_, _, _, _, ref generics, _) => (FnSpace, generics),
ItemImpl(_, _, ref generics, _, _, _) => (TypeSpace, generics),
ItemTy(_, ref generics) |
ItemEnum(_, ref generics) |
ItemStruct(_, ref generics) => {
allow_defaults = true;
(TypeSpace, generics)
}
ItemTrait(_, ref generics, _, _) => {
// Add in the self type parameter.
//
// Something of a hack: use the node id for the trait, also as
// the node id for the Self type parameter.
let param_id = item.id;
let parent = ccx.tcx.map.get_parent(param_id);
let def = ty::TypeParameterDef {
space: SelfSpace,
index: 0,
name: keywords::SelfType.name(),
def_id: tcx.map.local_def_id(param_id),
default_def_id: tcx.map.local_def_id(parent),
default: None,
object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
};
tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
opt_self = Some(def);
allow_defaults = true;
(TypeSpace, generics)
}
_ => (TypeSpace, &no_generics)
}
}
NodeForeignItem(item) => {
match item.node {
ForeignItemStatic(..) => (TypeSpace, &no_generics),
ForeignItemFn(_, ref generics) => (FnSpace, generics)
}
}
_ => (TypeSpace, &no_generics)
};
let empty_generics = ty::Generics::empty();
let base_generics = base_def_id.map_or(&empty_generics, |def_id| {
generics_of_def_id(ccx, def_id)
});
let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
let regions = early_lifetimes.iter().enumerate().map(|(i, l)| {
ty::RegionParameterDef {
name: l.lifetime.name,
space: space,
index: i as u32,
def_id: tcx.map.local_def_id(l.lifetime.id),
bounds: l.bounds.iter().map(|l| {
ast_region_to_region(tcx, l)
}).collect()
}
}).collect();
// Now create the real type parameters.
let types = ast_generics.ty_params.iter().enumerate().map(|(i, _)| {
get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32, allow_defaults)
}).collect();
let has_self = base_generics.has_self || opt_self.is_some();
let (regions, types) = match space {
SelfSpace => bug!(),
TypeSpace => {
assert_eq!(base_generics.regions.as_full_slice().len(), 0);
assert_eq!(base_generics.types.as_full_slice().len(), 0);
(VecPerParamSpace::new(vec![], regions, vec![]),
VecPerParamSpace::new(opt_self.into_iter().collect(), types, vec![]))
}
FnSpace => {
assert_eq!(base_generics.regions.len(FnSpace), 0);
assert_eq!(base_generics.types.len(FnSpace), 0);
(VecPerParamSpace::new(base_generics.regions.get_slice(SelfSpace).to_vec(),
base_generics.regions.get_slice(TypeSpace).to_vec(),
regions),
VecPerParamSpace::new(base_generics.types.get_slice(SelfSpace).to_vec(),
base_generics.types.get_slice(TypeSpace).to_vec(),
types))
}
};
// Debugging aid.
if tcx.has_attr(def_id, "rustc_object_lifetime_default") {
let object_lifetime_default_reprs: String =
types.as_full_slice().iter().map(|t| {
match t.object_lifetime_default {
ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
d => format!("{:?}", d),
}
}).collect::<Vec<String>>().join(",");
tcx.sess.span_err(tcx.map.span(node_id), &object_lifetime_default_reprs);
}
tcx.alloc_generics(ty::Generics {
regions: regions,
types: types,
has_self: has_self
})
})
}
fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
def_id: DefId)
-> Ty<'tcx> {
let node_id = if let Some(id) = ccx.tcx.map.as_local_node_id(def_id) {
id
} else {
return ccx.tcx.lookup_item_type(def_id).ty;
};
ccx.tcx.tcache.memoize(def_id, || {
use rustc::hir::map::*;
use rustc::hir::*;
let ty = match ccx.tcx.map.get(node_id) {
NodeItem(item) => {
match item.node {
ItemStatic(ref t, _, _) | ItemConst(ref t, _) => {
ccx.icx(&()).to_ty(&ExplicitRscope, &t)
}
ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
let tofd = AstConv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl,
Some(AnonTypeScope::new(def_id)));
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
ccx.tcx.mk_fn_def(def_id, substs, tofd)
}
ItemTy(ref t, ref generics) => {
ccx.icx(generics).to_ty(&ExplicitRscope, &t)
}
ItemEnum(ref ei, ref generics) => {
let def = convert_enum_def(ccx, item, ei);
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
ccx.tcx.mk_enum(def, substs)
}
ItemStruct(ref si, ref generics) => {
let def = convert_struct_def(ccx, item, si);
let substs = mk_item_substs(&ccx.icx(generics), item.span, def_id);
ccx.tcx.mk_struct(def, substs)
}
ItemDefaultImpl(..) |
ItemTrait(..) |
ItemImpl(..) |
ItemMod(..) |
ItemForeignMod(..) |
ItemExternCrate(..) |
ItemUse(..) => {
span_bug!(
item.span,
"compute_type_of_item: unexpected item type: {:?}",
item.node);
}
}
}
NodeForeignItem(foreign_item) => {
let abi = ccx.tcx.map.get_foreign_abi(node_id);
type_scheme_of_foreign_item(ccx, &foreign_item, abi)
match foreign_item.node {
ForeignItemFn(ref fn_decl, ref generics) => {
compute_type_of_foreign_fn_decl(
ccx, ccx.tcx.map.local_def_id(foreign_item.id),
fn_decl, generics, abi)
}
ForeignItemStatic(ref t, _) => {
ccx.icx(&()).to_ty(&ExplicitRscope, t)
}
}
}
x => {
bug!("unexpected sort of node in get_item_type_scheme(): {:?}",
x);
bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
}
};
write_ty_to_tcx(ccx, node_id, ty);
ty
})
}
fn type_scheme_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a,'tcx>,
def_id: DefId)
-> ty::TypeScheme<'tcx> {
if def_id.is_local() {
ty::TypeScheme {
generics: generics_of_def_id(ccx, def_id),
ty: type_of_def_id(ccx, def_id)
}
} else {
ccx.tcx.lookup_item_type(def_id)
}
}
fn type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
item: &hir::Item)
-> ty::TypeScheme<'tcx>
{
let item_def_id = ccx.tcx.map.local_def_id(item.id);
ccx.tcx.tcache.memoize(item_def_id, || {
// NB. Since the `memoized` function enters a new task, and we
// are giving this task access to the item `item`, we must
// register a read.
assert!(!ccx.tcx.map.is_inlined_def_id(item_def_id));
ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
compute_type_scheme_of_item(ccx, item)
})
}
fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
it: &hir::Item)
-> ty::TypeScheme<'tcx>
{
let tcx = ccx.tcx;
match it.node {
hir::ItemStatic(ref t, _, _) | hir::ItemConst(ref t, _) => {
let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &t);
ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
}
hir::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
let tofd = AstConv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &decl,
Some(AnonTypeScope::new(&ty_generics)));
let def_id = ccx.tcx.map.local_def_id(it.id);
let substs = mk_item_substs(tcx, &ty_generics);
let ty = tcx.mk_fn_def(def_id, substs, tofd);
ty::TypeScheme { ty: ty, generics: ty_generics }
}
hir::ItemTy(ref t, ref generics) => {
let ty_generics = ty_generics_for_type(ccx, generics);
let ty = ccx.icx(generics).to_ty(&ExplicitRscope, &t);
ty::TypeScheme { ty: ty, generics: ty_generics }
}
hir::ItemEnum(ref ei, ref generics) => {
let def = convert_enum_def(ccx, it, ei);
let ty_generics = ty_generics_for_type(ccx, generics);
let substs = mk_item_substs(tcx, &ty_generics);
let t = tcx.mk_enum(def, substs);
ty::TypeScheme { ty: t, generics: ty_generics }
}
hir::ItemStruct(ref si, ref generics) => {
let def = convert_struct_def(ccx, it, si);
let ty_generics = ty_generics_for_type(ccx, generics);
let substs = mk_item_substs(tcx, &ty_generics);
let t = tcx.mk_struct(def, substs);
ty::TypeScheme { ty: t, generics: ty_generics }
}
hir::ItemDefaultImpl(..) |
hir::ItemTrait(..) |
hir::ItemImpl(..) |
hir::ItemMod(..) |
hir::ItemForeignMod(..) |
hir::ItemExternCrate(..) |
hir::ItemUse(..) => {
span_bug!(
it.span,
"compute_type_scheme_of_item: unexpected item type: {:?}",
it.node);
}
}
}
fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
fn predicates_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
it: &hir::Item)
-> (ty::TypeScheme<'tcx>, ty::GenericPredicates<'tcx>)
{
let tcx = ccx.tcx;
let tag = type_scheme_of_item(ccx, it);
let scheme = TypeScheme { generics: tag.generics, ty: tag.ty };
-> ty::GenericPredicates<'tcx> {
let def_id = ccx.tcx.map.local_def_id(it.id);
let predicates = match it.node {
hir::ItemStatic(..) | hir::ItemConst(..) => {
ty::GenericPredicates::empty()
@ -1516,12 +1621,8 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
}
hir::ItemTy(_, ref generics) => {
ty_generic_predicates_for_type_or_impl(ccx, generics)
}
hir::ItemEnum(_, ref generics) => {
ty_generic_predicates_for_type_or_impl(ccx, generics)
}
hir::ItemTy(_, ref generics) |
hir::ItemEnum(_, ref generics) |
hir::ItemStruct(_, ref generics) => {
ty_generic_predicates_for_type_or_impl(ccx, generics)
}
@ -1534,68 +1635,16 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
hir::ItemForeignMod(..) => {
span_bug!(
it.span,
"compute_type_scheme_of_item: unexpected item type: {:?}",
"predicates_of_item: unexpected item type: {:?}",
it.node);
}
};
let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
predicates.clone());
let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id,
predicates.clone());
assert!(prev_predicates.is_none());
// Debugging aid.
if tcx.has_attr(ccx.tcx.map.local_def_id(it.id), "rustc_object_lifetime_default") {
let object_lifetime_default_reprs: String =
scheme.generics.types.as_full_slice().iter()
.map(|t| match t.object_lifetime_default {
ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
d => format!("{:?}", d),
})
.collect::<Vec<String>>()
.join(",");
tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
}
return (scheme, predicates);
}
fn type_scheme_of_foreign_item<'a, 'tcx>(
ccx: &CrateCtxt<'a, 'tcx>,
item: &hir::ForeignItem,
abi: abi::Abi)
-> ty::TypeScheme<'tcx>
{
let item_def_id = ccx.tcx.map.local_def_id(item.id);
ccx.tcx.tcache.memoize(item_def_id, || {
// NB. Since the `memoized` function enters a new task, and we
// are giving this task access to the item `item`, we must
// register a read.
assert!(!ccx.tcx.map.is_inlined_def_id(item_def_id));
ccx.tcx.dep_graph.read(DepNode::Hir(item_def_id));
compute_type_scheme_of_foreign_item(ccx, item, abi)
})
}
fn compute_type_scheme_of_foreign_item<'a, 'tcx>(
ccx: &CrateCtxt<'a, 'tcx>,
it: &hir::ForeignItem,
abi: abi::Abi)
-> ty::TypeScheme<'tcx>
{
match it.node {
hir::ForeignItemFn(ref fn_decl, ref generics) => {
compute_type_scheme_of_foreign_fn_decl(
ccx, ccx.tcx.map.local_def_id(it.id),
fn_decl, generics, abi)
}
hir::ForeignItemStatic(ref t, _) => {
ty::TypeScheme {
generics: ty::Generics::empty(),
ty: AstConv::ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, t)
}
}
}
predicates
}
fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@ -1605,11 +1654,8 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// map, and I regard each time that I use it as a personal and
// moral failing, but at the moment it seems like the only
// convenient way to extract the ABI. - ndm
let tcx = ccx.tcx;
let abi = tcx.map.get_foreign_abi(it.id);
let scheme = type_scheme_of_foreign_item(ccx, it, abi);
write_ty_to_tcx(ccx, it.id, scheme.ty);
let def_id = ccx.tcx.map.local_def_id(it.id);
type_scheme_of_def_id(ccx, def_id);
let predicates = match it.node {
hir::ForeignItemFn(_, ref generics) => {
@ -1620,21 +1666,10 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
};
let prev_predicates = tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id),
predicates);
let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
assert!(prev_predicates.is_none());
}
fn ty_generics_for_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics: &hir::Generics)
-> ty::Generics<'tcx> {
ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty(), true)
}
fn ty_generics_for_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, generics: &hir::Generics)
-> ty::Generics<'tcx> {
ty_generics(ccx, TypeSpace, generics, &ty::Generics::empty(), false)
}
fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
generics: &hir::Generics)
-> ty::GenericPredicates<'tcx>
@ -1642,50 +1677,6 @@ fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
}
fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
trait_id: ast::NodeId,
substs: &'tcx Substs<'tcx>,
ast_generics: &hir::Generics)
-> ty::Generics<'tcx>
{
debug!("ty_generics_for_trait(trait_id={:?}, substs={:?})",
ccx.tcx.map.local_def_id(trait_id), substs);
let mut generics = ty_generics_for_type(ccx, ast_generics);
// Add in the self type parameter.
//
// Something of a hack: use the node id for the trait, also as
// the node id for the Self type parameter.
let param_id = trait_id;
let parent = ccx.tcx.map.get_parent(param_id);
let def = ty::TypeParameterDef {
space: SelfSpace,
index: 0,
name: keywords::SelfType.name(),
def_id: ccx.tcx.map.local_def_id(param_id),
default_def_id: ccx.tcx.map.local_def_id(parent),
default: None,
object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
};
ccx.tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
generics.types.push(SelfSpace, def);
return generics;
}
fn ty_generics_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
generics: &hir::Generics,
base_generics: &ty::Generics<'tcx>)
-> ty::Generics<'tcx>
{
ty_generics(ccx, FnSpace, generics, base_generics, false)
}
fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
generics: &hir::Generics,
base_predicates: &ty::GenericPredicates<'tcx>)
@ -1859,42 +1850,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
result
}
fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
space: ParamSpace,
ast_generics: &hir::Generics,
base_generics: &ty::Generics<'tcx>,
allow_defaults: bool)
-> ty::Generics<'tcx>
{
let tcx = ccx.tcx;
let mut result = base_generics.clone();
let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
for (i, l) in early_lifetimes.iter().enumerate() {
let bounds = l.bounds.iter()
.map(|l| ast_region_to_region(tcx, l))
.collect();
let def = ty::RegionParameterDef { name: l.lifetime.name,
space: space,
index: i as u32,
def_id: ccx.tcx.map.local_def_id(l.lifetime.id),
bounds: bounds };
result.regions.push(space, def);
}
assert!(result.types.is_empty_in(space));
// Now create the real type parameters.
for i in 0..ast_generics.ty_params.len() {
let def =
get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32, allow_defaults);
debug!("ty_generics: def for type param: {:?}, {:?}", def, space);
result.types.push(space, def);
}
result
}
fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
path: &P<hir::Ty>,
space: ParamSpace,
@ -1969,6 +1924,9 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
debug!("get_or_create_type_parameter_def: def for type param: {:?}, {:?}",
def, space);
def
}
@ -2122,16 +2080,14 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
}
}
fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
fn compute_type_of_foreign_fn_decl<'a, 'tcx>(
ccx: &CrateCtxt<'a, 'tcx>,
id: DefId,
def_id: DefId,
decl: &hir::FnDecl,
ast_generics: &hir::Generics,
abi: abi::Abi)
-> ty::TypeScheme<'tcx>
-> Ty<'tcx>
{
let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
let rb = BindingRscope::new();
let input_tys = decl.inputs
.iter()
@ -2167,34 +2123,32 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
}
}
let substs = mk_item_substs(ccx.tcx, &ty_generics);
let t_fn = ccx.tcx.mk_fn_def(id, substs, ccx.tcx.mk_bare_fn(ty::BareFnTy {
let id = ccx.tcx.map.as_local_node_id(def_id).unwrap();
let substs = mk_item_substs(&ccx.icx(ast_generics), ccx.tcx.map.span(id), def_id);
ccx.tcx.mk_fn_def(def_id, substs, ccx.tcx.mk_bare_fn(ty::BareFnTy {
abi: abi,
unsafety: hir::Unsafety::Unsafe,
sig: ty::Binder(ty::FnSig {inputs: input_tys,
output: output,
variadic: decl.variadic}),
}));
ty::TypeScheme {
generics: ty_generics,
ty: t_fn
}
}))
}
pub fn mk_item_substs<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty_generics: &ty::Generics)
-> &'tcx Substs<'tcx>
{
let types =
ty_generics.types.map(
|def| tcx.mk_param_from_def(def));
pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
span: Span,
def_id: DefId)
-> &'tcx Substs<'tcx> {
let tcx = astconv.tcx();
// FIXME(eddyb) Do this request from Substs::for_item in librustc.
if let Err(ErrorReported) = astconv.get_generics(span, def_id) {
// No convenient way to recover from a cycle here. Just bail. Sorry!
tcx.sess.abort_if_errors();
bug!("ErrorReported returned, but no errors reports?")
}
let regions =
ty_generics.regions.map(
|def| def.to_early_bound_region());
tcx.mk_substs(Substs::new(types, regions))
Substs::for_item(tcx, def_id,
|def, _| def.to_early_bound_region(),
|def, _| tcx.mk_param_from_def(def))
}
/// Checks that all the type parameters on an impl

View File

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

View File

@ -8,10 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::ty::{self, TyCtxt};
use rustc::hir::def_id::DefId;
use rustc::ty;
use rustc::ty::subst::Substs;
use astconv::AstConv;
use std::cell::Cell;
use syntax_pos::Span;
@ -71,33 +73,34 @@ pub trait RegionScope {
}
#[derive(Copy, Clone)]
pub struct AnonTypeScope<'a> {
generics: &'a ty::Generics<'a>
pub struct AnonTypeScope {
enclosing_item: DefId
}
impl<'a, 'b, 'gcx, 'tcx> AnonTypeScope<'a> {
pub fn new(generics: &'a ty::Generics<'a>) -> AnonTypeScope<'a> {
impl<'gcx: 'tcx, 'tcx> AnonTypeScope {
pub fn new(enclosing_item: DefId) -> AnonTypeScope {
AnonTypeScope {
generics: generics
enclosing_item: enclosing_item
}
}
pub fn fresh_substs(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> {
pub fn fresh_substs(&self, astconv: &AstConv<'gcx, 'tcx>, span: Span)
-> &'tcx Substs<'tcx> {
use collect::mk_item_substs;
mk_item_substs(tcx, self.generics)
mk_item_substs(astconv, span, self.enclosing_item)
}
}
/// A scope wrapper which optionally allows anonymized types.
#[derive(Copy, Clone)]
pub struct MaybeWithAnonTypes<'a, R> {
pub struct MaybeWithAnonTypes<R> {
base_scope: R,
anon_scope: Option<AnonTypeScope<'a>>
anon_scope: Option<AnonTypeScope>
}
impl<'a, R: RegionScope> MaybeWithAnonTypes<'a, R> {
pub fn new(base_scope: R, anon_scope: Option<AnonTypeScope<'a>>) -> Self {
impl<R: RegionScope> MaybeWithAnonTypes<R> {
pub fn new(base_scope: R, anon_scope: Option<AnonTypeScope>) -> Self {
MaybeWithAnonTypes {
base_scope: base_scope,
anon_scope: anon_scope
@ -105,7 +108,7 @@ impl<'a, R: RegionScope> MaybeWithAnonTypes<'a, R> {
}
}
impl<'a, R: RegionScope> RegionScope for MaybeWithAnonTypes<'a, R> {
impl<R: RegionScope> RegionScope for MaybeWithAnonTypes<R> {
fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
self.base_scope.object_lifetime_default(span)
}

View File

@ -16,8 +16,7 @@
use dep_graph::DepTrackingMapConfig;
use hir::def_id::DefId;
use middle::resolve_lifetime as rl;
use rustc::ty::subst;
use rustc::ty::subst::ParamSpace;
use rustc::ty::subst::{self, ParamSpace, Substs};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::maps::ItemVariances;
use rustc::hir::map as hir_map;
@ -370,8 +369,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_substs(
generics,
def.did,
item_type.generics.types.get_slice(subst::TypeSpace),
item_type.generics.regions.get_slice(subst::TypeSpace),
item_type.generics.types.as_full_slice(),
item_type.generics.regions.as_full_slice(),
substs,
variance);
}
@ -449,7 +448,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
def_id: DefId,
type_param_defs: &[ty::TypeParameterDef<'tcx>],
region_param_defs: &[ty::RegionParameterDef],
substs: &subst::Substs<'tcx>,
substs: &Substs<'tcx>,
variance: VarianceTermPtr<'a>) {
debug!("add_constraints_from_substs(def_id={:?}, substs={:?}, variance={:?})",
def_id,

View File

@ -16,6 +16,7 @@
//! inferred is then written into the `variance_map` in the tcx.
use rustc::ty;
use rustc::ty::subst;
use std::rc::Rc;
use super::constraints::*;
@ -108,7 +109,9 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
let num_inferred = self.terms_cx.num_inferred();
while index < num_inferred {
let item_id = inferred_infos[index].item_id;
let mut item_variances = ty::ItemVariances::empty();
let (mut rs, mut rt, mut rf) = (vec![], vec![], vec![]);
let (mut ts, mut tt, mut tf) = (vec![], vec![], vec![]);
while index < num_inferred && inferred_infos[index].item_id == item_id {
let info = &inferred_infos[index];
@ -116,13 +119,34 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
debug!("Index {} Info {} / {:?} / {:?} Variance {:?}",
index, info.index, info.kind, info.space, variance);
match info.kind {
TypeParam => { item_variances.types.push(info.space, variance); }
RegionParam => { item_variances.regions.push(info.space, variance); }
TypeParam => {
let types = match info.space {
subst::SelfSpace => &mut ts,
subst::TypeSpace => &mut tt,
subst::FnSpace => &mut tf
};
assert_eq!(types.len(), info.index);
types.push(variance);
}
RegionParam => {
let regions = match info.space {
subst::SelfSpace => &mut rs,
subst::TypeSpace => &mut rt,
subst::FnSpace => &mut rf
};
assert_eq!(regions.len(), info.index);
regions.push(variance);
}
}
index += 1;
}
let item_variances = ty::ItemVariances {
regions: subst::VecPerParamSpace::new(rs, rt, rf),
types: subst::VecPerParamSpace::new(ts, tt, tf)
};
debug!("item_id={} item_variances={:?}",
item_id,
item_variances);

View File

@ -161,7 +161,7 @@ pub fn build_external_trait<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tc
let def = tcx.lookup_trait_def(did);
let trait_items = tcx.trait_items(did).clean(cx);
let predicates = tcx.lookup_predicates(did);
let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx);
let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx);
let generics = filter_non_trait_generics(did, generics);
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
clean::Trait {
@ -189,7 +189,7 @@ fn build_external_function<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx
let predicates = tcx.lookup_predicates(did);
clean::Function {
decl: decl,
generics: (&t.generics, &predicates, subst::FnSpace).clean(cx),
generics: (t.generics, &predicates, subst::FnSpace).clean(cx),
unsafety: style,
constness: constness,
abi: abi,
@ -209,7 +209,7 @@ fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
&[..] if variant.kind == ty::VariantKind::Tuple => doctree::Tuple,
_ => doctree::Plain,
},
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
fields: variant.fields.clean(cx),
fields_stripped: false,
}
@ -222,7 +222,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
match t.ty.sty {
ty::TyEnum(edef, _) if !tcx.sess.cstore.is_typedef(did) => {
return clean::EnumItem(clean::Enum {
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
variants_stripped: false,
variants: edef.variants.clean(cx),
})
@ -232,7 +232,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
clean::TypedefItem(clean::Typedef {
type_: t.ty.clean(cx),
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
}, false)
}
@ -389,15 +389,11 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
}
ty::TypeTraitItem(ref assoc_ty) => {
let did = assoc_ty.def_id;
let type_scheme = ty::TypeScheme {
ty: assoc_ty.ty.unwrap(),
generics: ty::Generics::empty()
};
// Not sure the choice of ParamSpace actually matters here,
// because an associated type won't have generics on the LHS
let typedef = clean::Typedef {
type_: type_scheme.ty.clean(cx),
generics: (&type_scheme.generics,
type_: assoc_ty.ty.unwrap().clean(cx),
generics: (&ty::Generics::empty(),
&ty::GenericPredicates::empty(),
subst::TypeSpace).clean(cx)
};
@ -438,7 +434,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
provided_trait_methods: provided,
trait_: trait_,
for_: for_,
generics: (&ty.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (ty.generics, &predicates, subst::TypeSpace).clean(cx),
items: trait_items,
polarity: polarity.map(|p| { p.clean(cx) }),
}),

View File

@ -41,7 +41,7 @@ use rustc::hir::def::Def;
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
use rustc::hir::fold::Folder;
use rustc::hir::print as pprust;
use rustc::ty::subst::{self, ParamSpace, VecPerParamSpace};
use rustc::ty::subst::{self, ParamSpace, Substs, VecPerParamSpace};
use rustc::ty;
use rustc::middle::stability;
@ -631,7 +631,7 @@ impl Clean<TyParamBound> for hir::TyParamBound {
}
fn external_path_params(cx: &DocContext, trait_did: Option<DefId>,
bindings: Vec<TypeBinding>, substs: &subst::Substs) -> PathParameters {
bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
let lifetimes = substs.regions.get_slice(subst::TypeSpace)
.iter()
.filter_map(|v| v.clean(cx))
@ -676,7 +676,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>,
// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
// from Fn<(A, B,), C> to Fn(A, B) -> C
fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>,
bindings: Vec<TypeBinding>, substs: &subst::Substs) -> Path {
bindings: Vec<TypeBinding>, substs: &Substs) -> Path {
Path {
global: false,
segments: vec![PathSegment {
@ -692,20 +692,20 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
Some(tcx) => tcx,
None => return RegionBound(Lifetime::statik())
};
let empty = subst::Substs::empty();
let empty = Substs::empty(tcx);
let (did, path) = match *self {
ty::BoundSend =>
(tcx.lang_items.send_trait().unwrap(),
external_path(cx, "Send", None, vec![], &empty)),
external_path(cx, "Send", None, vec![], empty)),
ty::BoundSized =>
(tcx.lang_items.sized_trait().unwrap(),
external_path(cx, "Sized", None, vec![], &empty)),
external_path(cx, "Sized", None, vec![], empty)),
ty::BoundCopy =>
(tcx.lang_items.copy_trait().unwrap(),
external_path(cx, "Copy", None, vec![], &empty)),
external_path(cx, "Copy", None, vec![], empty)),
ty::BoundSync =>
(tcx.lang_items.sync_trait().unwrap(),
external_path(cx, "Sync", None, vec![], &empty)),
external_path(cx, "Sync", None, vec![], empty)),
};
inline::record_extern_fqn(cx, did, TypeTrait);
TraitBound(PolyTrait {
@ -765,7 +765,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
}
}
impl<'tcx> Clean<Option<Vec<TyParamBound>>> for subst::Substs<'tcx> {
impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
let mut v = Vec::new();
v.extend(self.regions.as_full_slice().iter().filter_map(|r| r.clean(cx))
@ -891,7 +891,7 @@ impl<'a> Clean<WherePredicate> for ty::Predicate<'a> {
impl<'a> Clean<WherePredicate> for ty::TraitPredicate<'a> {
fn clean(&self, cx: &DocContext) -> WherePredicate {
WherePredicate::BoundPredicate {
ty: self.trait_ref.substs.self_ty().clean(cx).unwrap(),
ty: self.trait_ref.self_ty().clean(cx),
bounds: vec![self.trait_ref.clean(cx)]
}
}
@ -1353,7 +1353,7 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
predicates: self.predicates.predicates[method_start..].to_vec()
};
let generics = (&self.generics, &method_predicates,
let generics = (self.generics, &method_predicates,
subst::FnSpace).clean(cx);
let mut decl = (self.def_id, &self.fty.sig).clean(cx);
match self.explicit_self {
@ -2923,7 +2923,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedType<'tcx> {
// applied to this associated type in question.
let def = cx.tcx().lookup_trait_def(did);
let predicates = cx.tcx().lookup_predicates(did);
let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx);
let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx);
generics.where_predicates.iter().filter_map(|pred| {
let (name, self_type, trait_, bounds) = match *pred {
WherePredicate::BoundPredicate {