rustc: reduce Substs and Generics to a simple immutable API.
This commit is contained in:
parent
bfdfa1ce1d
commit
4158673ad7
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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 ")?;
|
||||
|
@ -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()
|
||||
|
@ -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(),
|
||||
|
@ -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>
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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>> }
|
||||
|
@ -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,
|
||||
|
@ -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> {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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(),
|
||||
|
@ -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)
|
||||
//
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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| {
|
||||
|
@ -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 =
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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())?;
|
||||
|
@ -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>);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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],
|
||||
|
@ -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(|| {
|
||||
|
@ -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);
|
||||
|
@ -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, &[])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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[..])
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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(|_| {
|
||||
|
@ -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`.
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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) }),
|
||||
}),
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user