rustc: remove type information from TraitDef.
This commit is contained in:
parent
f50dbd580f
commit
3f338eed99
@ -277,7 +277,7 @@ pub trait CrateStore<'tcx> {
|
||||
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> 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 trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef;
|
||||
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
|
||||
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
|
||||
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
|
||||
@ -423,7 +423,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
||||
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> 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>
|
||||
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef
|
||||
{ bug!("trait_def") }
|
||||
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
|
||||
{ bug!("adt_def") }
|
||||
|
@ -244,11 +244,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
for item in self.tcx.get_attrs(def_id).iter() {
|
||||
if item.check_name("rustc_on_unimplemented") {
|
||||
let err_sp = item.meta().span.substitute_dummy(span);
|
||||
let def = self.tcx.lookup_trait_def(trait_ref.def_id);
|
||||
let trait_str = def.trait_ref.to_string();
|
||||
let trait_str = self.tcx.item_path_str(trait_ref.def_id);
|
||||
if let Some(istring) = item.value_str() {
|
||||
let istring = &*istring.as_str();
|
||||
let generic_map = def.generics.types.iter().map(|param| {
|
||||
let generics = self.tcx.item_generics(trait_ref.def_id);
|
||||
let generic_map = generics.types.iter().map(|param| {
|
||||
(param.name.as_str().to_string(),
|
||||
trait_ref.substs.type_for_def(param).to_string())
|
||||
}).collect::<FxHashMap<String, String>>();
|
||||
|
@ -21,7 +21,8 @@ use super::elaborate_predicates;
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use traits;
|
||||
use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::subst::Substs;
|
||||
use syntax::ast;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
@ -126,9 +127,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn supertraits_reference_self(self, trait_def_id: DefId) -> bool {
|
||||
let trait_def = self.lookup_trait_def(trait_def_id);
|
||||
let trait_ref = trait_def.trait_ref.clone();
|
||||
let trait_ref = trait_ref.to_poly_trait_ref();
|
||||
let trait_ref = ty::Binder(ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: Substs::identity_for_item(self, trait_def_id)
|
||||
});
|
||||
let predicates = self.item_super_predicates(trait_def_id);
|
||||
predicates
|
||||
.predicates
|
||||
@ -317,8 +319,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Compute supertraits of current trait lazily.
|
||||
if supertraits.is_none() {
|
||||
let trait_def = self.lookup_trait_def(trait_def_id);
|
||||
let trait_ref = ty::Binder(trait_def.trait_ref.clone());
|
||||
let trait_ref = ty::Binder(ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: Substs::identity_for_item(self, trait_def_id)
|
||||
});
|
||||
supertraits = Some(traits::supertraits(self, trait_ref).collect());
|
||||
}
|
||||
|
||||
|
@ -297,18 +297,18 @@ impl<'a, 'gcx, 'tcx> Node {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Ancestors<'a, 'tcx: 'a> {
|
||||
trait_def: &'a TraitDef<'tcx>,
|
||||
pub struct Ancestors<'a> {
|
||||
trait_def: &'a TraitDef,
|
||||
current_source: Option<Node>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Iterator for Ancestors<'a, 'tcx> {
|
||||
impl<'a> Iterator for Ancestors<'a> {
|
||||
type Item = Node;
|
||||
fn next(&mut self) -> Option<Node> {
|
||||
let cur = self.current_source.take();
|
||||
if let Some(Node::Impl(cur_impl)) = cur {
|
||||
let parent = self.trait_def.specialization_graph.borrow().parent(cur_impl);
|
||||
if parent == self.trait_def.def_id() {
|
||||
if parent == self.trait_def.def_id {
|
||||
self.current_source = Some(Node::Trait(parent));
|
||||
} else {
|
||||
self.current_source = Some(Node::Impl(parent));
|
||||
@ -332,7 +332,7 @@ impl<T> NodeItem<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Ancestors<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> Ancestors<'a> {
|
||||
/// Search the items from the given ancestors, returning each definition
|
||||
/// with the given name and the given kind.
|
||||
#[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
|
||||
@ -347,9 +347,7 @@ impl<'a, 'gcx, 'tcx> Ancestors<'a, 'tcx> {
|
||||
|
||||
/// Walk up the specialization ancestors of a given impl, starting with that
|
||||
/// impl itself.
|
||||
pub fn ancestors<'a, 'tcx>(trait_def: &'a TraitDef<'tcx>,
|
||||
start_from_impl: DefId)
|
||||
-> Ancestors<'a, 'tcx> {
|
||||
pub fn ancestors<'a>(trait_def: &'a TraitDef, start_from_impl: DefId) -> Ancestors<'a> {
|
||||
Ancestors {
|
||||
trait_def: trait_def,
|
||||
current_source: Some(Node::Impl(start_from_impl)),
|
||||
|
@ -66,7 +66,7 @@ pub struct CtxtArenas<'tcx> {
|
||||
|
||||
// references
|
||||
generics: TypedArena<ty::Generics<'tcx>>,
|
||||
trait_def: TypedArena<ty::TraitDef<'tcx>>,
|
||||
trait_def: TypedArena<ty::TraitDef>,
|
||||
adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
|
||||
mir: TypedArena<RefCell<Mir<'tcx>>>,
|
||||
}
|
||||
@ -683,19 +683,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
self.global_interners.arenas.mir.alloc(RefCell::new(mir))
|
||||
}
|
||||
|
||||
pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
|
||||
-> &'gcx ty::TraitDef<'gcx> {
|
||||
let did = def.trait_ref.def_id;
|
||||
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
|
||||
}
|
||||
|
||||
pub fn alloc_trait_def(self, def: ty::TraitDef<'gcx>)
|
||||
-> &'gcx ty::TraitDef<'gcx> {
|
||||
pub fn alloc_trait_def(self, def: ty::TraitDef) -> &'gcx ty::TraitDef {
|
||||
self.global_interners.arenas.trait_def.alloc(def)
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
|
||||
dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
|
||||
dep_map_ty! { AssociatedItemDefIds: AssociatedItemDefIds(DefId) -> Rc<Vec<DefId>> }
|
||||
dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>> }
|
||||
dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef<'tcx> }
|
||||
dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef }
|
||||
dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> }
|
||||
dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>> }
|
||||
dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
|
||||
|
@ -629,10 +629,6 @@ pub struct RegionParameterDef<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> RegionParameterDef<'tcx> {
|
||||
pub fn to_early_bound_region(&self) -> ty::Region {
|
||||
ty::ReEarlyBound(self.to_early_bound_region_data())
|
||||
}
|
||||
|
||||
pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
|
||||
ty::EarlyBoundRegion {
|
||||
index: self.index,
|
||||
@ -2400,7 +2396,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
/// Given the did of a trait, returns its canonical trait ref.
|
||||
pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef<'gcx> {
|
||||
pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef {
|
||||
lookup_locally_or_in_crate_store(
|
||||
"trait_defs", did, &self.trait_defs,
|
||||
|| self.alloc_trait_def(self.sess.cstore.trait_def(self.global_tcx(), did))
|
||||
|
@ -165,6 +165,14 @@ impl<'tcx> Decodable for Kind<'tcx> {
|
||||
pub type Substs<'tcx> = Slice<Kind<'tcx>>;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
/// Creates a Substs that maps each generic parameter to itself.
|
||||
pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
|
||||
-> &'tcx Substs<'tcx> {
|
||||
Substs::for_item(tcx, def_id, |def, _| {
|
||||
tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
|
||||
}, |def, _| tcx.mk_param_from_def(def))
|
||||
}
|
||||
|
||||
/// Creates a Substs for generic parameter definitions,
|
||||
/// by calling closures to obtain each region and type.
|
||||
/// The closures get to observe the Substs as they're
|
||||
|
@ -19,7 +19,9 @@ use hir;
|
||||
use util::nodemap::FxHashMap;
|
||||
|
||||
/// A trait's definition with type information.
|
||||
pub struct TraitDef<'tcx> {
|
||||
pub struct TraitDef {
|
||||
pub def_id: DefId,
|
||||
|
||||
pub unsafety: hir::Unsafety,
|
||||
|
||||
/// If `true`, then this trait had the `#[rustc_paren_sugar]`
|
||||
@ -28,15 +30,6 @@ pub struct TraitDef<'tcx> {
|
||||
/// be usable with the sugar (or without it).
|
||||
pub paren_sugar: bool,
|
||||
|
||||
/// Generic type definitions. Note that `Self` is listed in here
|
||||
/// as having a single bound, the trait itself (e.g., in the trait
|
||||
/// `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: &'tcx ty::Generics<'tcx>,
|
||||
|
||||
pub trait_ref: ty::TraitRef<'tcx>,
|
||||
|
||||
// Impls of a trait. To allow for quicker lookup, the impls are indexed by a
|
||||
// simplified version of their `Self` type: impls with a simplifiable `Self`
|
||||
// are stored in `nonblanket_impls` keyed by it, while all other impls are
|
||||
@ -72,18 +65,16 @@ pub struct TraitDef<'tcx> {
|
||||
pub def_path_hash: u64,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||
pub fn new(unsafety: hir::Unsafety,
|
||||
impl<'a, 'gcx, 'tcx> TraitDef {
|
||||
pub fn new(def_id: DefId,
|
||||
unsafety: hir::Unsafety,
|
||||
paren_sugar: bool,
|
||||
generics: &'tcx ty::Generics<'tcx>,
|
||||
trait_ref: ty::TraitRef<'tcx>,
|
||||
def_path_hash: u64)
|
||||
-> TraitDef<'tcx> {
|
||||
-> TraitDef {
|
||||
TraitDef {
|
||||
def_id: def_id,
|
||||
paren_sugar: paren_sugar,
|
||||
unsafety: unsafety,
|
||||
generics: generics,
|
||||
trait_ref: trait_ref,
|
||||
nonblanket_impls: RefCell::new(FxHashMap()),
|
||||
blanket_impls: RefCell::new(vec![]),
|
||||
flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS),
|
||||
@ -92,10 +83,6 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn def_id(&self) -> DefId {
|
||||
self.trait_ref.def_id
|
||||
}
|
||||
|
||||
// returns None if not yet calculated
|
||||
pub fn object_safety(&self) -> Option<bool> {
|
||||
if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
|
||||
@ -117,11 +104,11 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||
}
|
||||
|
||||
fn write_trait_impls(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) {
|
||||
tcx.dep_graph.write(DepNode::TraitImpls(self.trait_ref.def_id));
|
||||
tcx.dep_graph.write(DepNode::TraitImpls(self.def_id));
|
||||
}
|
||||
|
||||
fn read_trait_impls(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) {
|
||||
tcx.dep_graph.read(DepNode::TraitImpls(self.trait_ref.def_id));
|
||||
tcx.dep_graph.read(DepNode::TraitImpls(self.def_id));
|
||||
}
|
||||
|
||||
/// Records a basic trait-to-implementation mapping.
|
||||
@ -203,13 +190,13 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||
.insert(tcx, impl_def_id)
|
||||
}
|
||||
|
||||
pub fn ancestors(&'a self, of_impl: DefId) -> specialization_graph::Ancestors<'a, 'tcx> {
|
||||
pub fn ancestors(&'a self, of_impl: DefId) -> specialization_graph::Ancestors<'a> {
|
||||
specialization_graph::ancestors(self, of_impl)
|
||||
}
|
||||
|
||||
pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, mut f: F) {
|
||||
self.read_trait_impls(tcx);
|
||||
tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
|
||||
tcx.populate_implementations_for_trait_if_necessary(self.def_id);
|
||||
|
||||
for &impl_def_id in self.blanket_impls.borrow().iter() {
|
||||
f(impl_def_id);
|
||||
@ -231,7 +218,7 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||
{
|
||||
self.read_trait_impls(tcx);
|
||||
|
||||
tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
|
||||
tcx.populate_implementations_for_trait_if_necessary(self.def_id);
|
||||
|
||||
for &impl_def_id in self.blanket_impls.borrow().iter() {
|
||||
f(impl_def_id);
|
||||
|
@ -432,10 +432,11 @@ impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
|
||||
impl fmt::Debug for ty::TraitDef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
|
||||
self.generics, self.trait_ref)
|
||||
ty::tls::with(|tcx| {
|
||||
write!(f, "{}", tcx.item_path_str(self.def_id))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
||||
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index)
|
||||
}
|
||||
|
||||
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
|
||||
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef
|
||||
{
|
||||
self.dep_graph.read(DepNode::MetaData(def));
|
||||
self.get_crate_data(def.krate).get_trait_def(def.index, tcx)
|
||||
|
@ -531,16 +531,15 @@ impl<'a, 'tcx> CrateMetadata {
|
||||
pub fn get_trait_def(&self,
|
||||
item_id: DefIndex,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
-> ty::TraitDef<'tcx> {
|
||||
-> ty::TraitDef {
|
||||
let data = match self.entry(item_id).kind {
|
||||
EntryKind::Trait(data) => data.decode(self),
|
||||
_ => bug!(),
|
||||
};
|
||||
|
||||
ty::TraitDef::new(data.unsafety,
|
||||
ty::TraitDef::new(self.local_def_id(item_id),
|
||||
data.unsafety,
|
||||
data.paren_sugar,
|
||||
tcx.item_generics(self.local_def_id(item_id)),
|
||||
data.trait_ref.decode((self, tcx)),
|
||||
self.def_path(item_id).unwrap().deterministic_hash(tcx))
|
||||
}
|
||||
|
||||
|
@ -730,7 +730,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
unsafety: trait_def.unsafety,
|
||||
paren_sugar: trait_def.paren_sugar,
|
||||
has_default_impl: tcx.trait_has_default_impl(def_id),
|
||||
trait_ref: self.lazy(&trait_def.trait_ref),
|
||||
super_predicates: self.lazy(&tcx.item_super_predicates(def_id)),
|
||||
};
|
||||
|
||||
|
@ -278,7 +278,6 @@ pub struct TraitData<'tcx> {
|
||||
pub unsafety: hir::Unsafety,
|
||||
pub paren_sugar: bool,
|
||||
pub has_default_impl: bool,
|
||||
pub trait_ref: Lazy<ty::TraitRef<'tcx>>,
|
||||
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ pub trait AstConv<'gcx, 'tcx> {
|
||||
/// Returns the `TraitDef` for a given trait. This allows you to
|
||||
/// figure out the set of type parameters defined on the trait.
|
||||
fn get_trait_def(&self, span: Span, id: DefId)
|
||||
-> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>;
|
||||
-> Result<&'tcx ty::TraitDef, ErrorReported>;
|
||||
|
||||
/// Ensure that the super-predicates for the trait with the given
|
||||
/// id are available and also for the transitive set of
|
||||
|
@ -192,13 +192,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
m_name,
|
||||
trait_def_id);
|
||||
|
||||
let trait_def = self.tcx.lookup_trait_def(trait_def_id);
|
||||
|
||||
if let Some(ref input_types) = opt_input_types {
|
||||
assert_eq!(trait_def.generics.types.len() - 1, input_types.len());
|
||||
}
|
||||
assert!(trait_def.generics.regions.is_empty());
|
||||
|
||||
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
||||
let substs = Substs::for_item(self.tcx,
|
||||
trait_def_id,
|
||||
|
@ -1040,7 +1040,7 @@ fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trait_def: &ty::TraitDef<'tcx>,
|
||||
trait_def: &ty::TraitDef,
|
||||
impl_id: DefId,
|
||||
impl_item: &hir::ImplItem)
|
||||
{
|
||||
@ -1400,7 +1400,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn get_trait_def(&self, _: Span, id: DefId)
|
||||
-> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
|
||||
-> Result<&'tcx ty::TraitDef, ErrorReported>
|
||||
{
|
||||
Ok(self.tcx().lookup_trait_def(id))
|
||||
}
|
||||
|
@ -290,12 +290,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
}
|
||||
});
|
||||
|
||||
let trait_def = self.tcx().lookup_trait_def(trait_def_id);
|
||||
|
||||
let has_ty_params =
|
||||
trait_def.generics
|
||||
.types
|
||||
.len() > 1;
|
||||
let has_ty_params = self.tcx().item_generics(trait_def_id).types.len() > 1;
|
||||
|
||||
// We use an if-else here, since the generics will also trigger
|
||||
// an extraneous error message when we find predicates like
|
||||
|
@ -329,20 +329,21 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
|
||||
}
|
||||
|
||||
/// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
|
||||
fn get_trait_def(&self, trait_id: DefId)
|
||||
-> &'tcx ty::TraitDef<'tcx>
|
||||
fn get_trait_def(&self, def_id: DefId)
|
||||
-> &'tcx ty::TraitDef
|
||||
{
|
||||
let tcx = self.tcx;
|
||||
|
||||
if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
|
||||
if let Some(trait_id) = tcx.map.as_local_node_id(def_id) {
|
||||
let item = match tcx.map.get(trait_id) {
|
||||
hir_map::NodeItem(item) => item,
|
||||
_ => bug!("get_trait_def({:?}): not an item", trait_id)
|
||||
};
|
||||
|
||||
generics_of_def_id(self, def_id);
|
||||
trait_def_of_item(self, &item)
|
||||
} else {
|
||||
tcx.lookup_trait_def(trait_id)
|
||||
tcx.lookup_trait_def(def_id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +393,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn get_trait_def(&self, span: Span, id: DefId)
|
||||
-> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
|
||||
-> Result<&'tcx ty::TraitDef, ErrorReported>
|
||||
{
|
||||
self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
|
||||
Ok(self.ccx.get_trait_def(id))
|
||||
@ -716,6 +717,7 @@ fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
|
||||
fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||
let tcx = ccx.tcx;
|
||||
debug!("convert: item {} with id {}", it.name, it.id);
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
match it.node {
|
||||
// These don't define types.
|
||||
hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
|
||||
@ -726,7 +728,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||
}
|
||||
}
|
||||
hir::ItemEnum(ref enum_definition, _) => {
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
let ty = type_of_def_id(ccx, def_id);
|
||||
let generics = generics_of_def_id(ccx, def_id);
|
||||
let predicates = predicates_of_item(ccx, it);
|
||||
@ -756,7 +757,6 @@ 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);
|
||||
generics_of_def_id(ccx, def_id);
|
||||
let mut ty_predicates =
|
||||
ty_generic_predicates(ccx, generics, None, vec![], false);
|
||||
@ -786,8 +786,8 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||
tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
|
||||
},
|
||||
hir::ItemTrait(.., ref trait_items) => {
|
||||
let trait_def = trait_def_of_item(ccx, it);
|
||||
let def_id = trait_def.trait_ref.def_id;
|
||||
generics_of_def_id(ccx, def_id);
|
||||
trait_def_of_item(ccx, it);
|
||||
let _: Result<(), ErrorReported> = // any error is already reported, can ignore
|
||||
ccx.ensure_super_predicates(it.span, def_id);
|
||||
convert_trait_predicates(ccx, it);
|
||||
@ -838,7 +838,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||
},
|
||||
hir::ItemStruct(ref struct_def, _) |
|
||||
hir::ItemUnion(ref struct_def, _) => {
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
let ty = type_of_def_id(ccx, def_id);
|
||||
let generics = generics_of_def_id(ccx, def_id);
|
||||
let predicates = predicates_of_item(ccx, it);
|
||||
@ -855,13 +854,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||
},
|
||||
hir::ItemTy(_, ref generics) => {
|
||||
ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
type_of_def_id(ccx, def_id);
|
||||
generics_of_def_id(ccx, def_id);
|
||||
predicates_of_item(ccx, it);
|
||||
},
|
||||
_ => {
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
type_of_def_id(ccx, def_id);
|
||||
generics_of_def_id(ccx, def_id);
|
||||
predicates_of_item(ccx, it);
|
||||
@ -1155,10 +1152,15 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
|
||||
// In-scope when converting the superbounds for `Trait` are
|
||||
// that `Self:Trait` as well as any bounds that appear on the
|
||||
// generic types:
|
||||
let trait_def = trait_def_of_item(ccx, item);
|
||||
generics_of_def_id(ccx, trait_def_id);
|
||||
trait_def_of_item(ccx, item);
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: Substs::identity_for_item(tcx, trait_def_id)
|
||||
};
|
||||
let self_predicate = ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates: vec![trait_def.trait_ref.to_predicate()]
|
||||
predicates: vec![trait_ref.to_predicate()]
|
||||
};
|
||||
let scope = &(generics, &self_predicate);
|
||||
|
||||
@ -1203,54 +1205,41 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
|
||||
def_ids
|
||||
}
|
||||
|
||||
fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
it: &hir::Item)
|
||||
-> &'tcx ty::TraitDef<'tcx>
|
||||
{
|
||||
fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'tcx ty::TraitDef {
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
let tcx = ccx.tcx;
|
||||
|
||||
if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
|
||||
return def.clone();
|
||||
}
|
||||
tcx.trait_defs.memoize(def_id, || {
|
||||
let unsafety = match it.node {
|
||||
hir::ItemTrait(unsafety, ..) => unsafety,
|
||||
_ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
|
||||
};
|
||||
|
||||
let (unsafety, generics) = match it.node {
|
||||
hir::ItemTrait(unsafety, ref generics, _, _) => {
|
||||
(unsafety, generics)
|
||||
let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
|
||||
if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
|
||||
let mut err = ccx.tcx.sess.struct_span_err(
|
||||
it.span,
|
||||
"the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
|
||||
which traits can use parenthetical notation");
|
||||
help!(&mut err,
|
||||
"add `#![feature(unboxed_closures)]` to \
|
||||
the crate attributes to use it");
|
||||
err.emit();
|
||||
}
|
||||
_ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
|
||||
};
|
||||
|
||||
let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
|
||||
if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
|
||||
let mut err = ccx.tcx.sess.struct_span_err(
|
||||
it.span,
|
||||
"the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
|
||||
which traits can use parenthetical notation");
|
||||
help!(&mut err,
|
||||
"add `#![feature(unboxed_closures)]` to \
|
||||
the crate attributes to use it");
|
||||
err.emit();
|
||||
}
|
||||
|
||||
let ty_generics = generics_of_def_id(ccx, def_id);
|
||||
let substs = mk_item_substs(&ccx.icx(generics), it.span, def_id);
|
||||
|
||||
let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
|
||||
|
||||
let trait_ref = ty::TraitRef::new(def_id, substs);
|
||||
let trait_def = ty::TraitDef::new(unsafety, paren_sugar, ty_generics, trait_ref,
|
||||
def_path_hash);
|
||||
|
||||
tcx.intern_trait_def(trait_def)
|
||||
let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
|
||||
tcx.alloc_trait_def(ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash))
|
||||
})
|
||||
}
|
||||
|
||||
fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
|
||||
let tcx = ccx.tcx;
|
||||
let trait_def = trait_def_of_item(ccx, it);
|
||||
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
|
||||
generics_of_def_id(ccx, def_id);
|
||||
trait_def_of_item(ccx, it);
|
||||
|
||||
let (generics, items) = match it.node {
|
||||
hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
|
||||
ref s => {
|
||||
@ -1272,7 +1261,11 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
|
||||
|
||||
// Add in a predicate that `Self:Trait` (where `Trait` is the
|
||||
// current trait). This is needed for builtin bounds.
|
||||
let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: Substs::identity_for_item(tcx, def_id)
|
||||
};
|
||||
let self_predicate = trait_ref.to_poly_trait_ref().to_predicate();
|
||||
base_predicates.push(self_predicate);
|
||||
|
||||
// add in the explicit where-clauses
|
||||
@ -1282,7 +1275,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
|
||||
let assoc_predicates = predicates_for_associated_types(ccx,
|
||||
generics,
|
||||
&trait_predicates,
|
||||
trait_def.trait_ref,
|
||||
trait_ref,
|
||||
items);
|
||||
trait_predicates.predicates.extend(assoc_predicates);
|
||||
|
||||
@ -1581,7 +1574,10 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
|
||||
ccx.tcx.mk_closure(def_id, Substs::for_item(
|
||||
ccx.tcx, def_id,
|
||||
|def, _| ccx.tcx.mk_region(def.to_early_bound_region()),
|
||||
|def, _| {
|
||||
let region = def.to_early_bound_region_data();
|
||||
ccx.tcx.mk_region(ty::ReEarlyBound(region))
|
||||
},
|
||||
|def, _| ccx.tcx.mk_param_from_def(def)
|
||||
))
|
||||
}
|
||||
@ -2095,7 +2091,5 @@ pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
bug!("ErrorReported returned, but no errors reports?")
|
||||
}
|
||||
|
||||
Substs::for_item(tcx, def_id,
|
||||
|def, _| tcx.mk_region(def.to_early_bound_region()),
|
||||
|def, _| tcx.mk_param_from_def(def))
|
||||
Substs::identity_for_item(tcx, def_id)
|
||||
}
|
||||
|
@ -97,9 +97,13 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
hir::ItemTrait(..) => {
|
||||
let trait_def = tcx.lookup_trait_def(did);
|
||||
self.add_constraints_from_trait_ref(&trait_def.generics,
|
||||
trait_def.trait_ref,
|
||||
let generics = tcx.item_generics(did);
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: did,
|
||||
substs: Substs::identity_for_item(tcx, did)
|
||||
};
|
||||
self.add_constraints_from_trait_ref(generics,
|
||||
trait_ref,
|
||||
self.invariant);
|
||||
}
|
||||
|
||||
@ -279,7 +283,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
trait_ref,
|
||||
variance);
|
||||
|
||||
let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id);
|
||||
let trait_generics = self.tcx().item_generics(trait_ref.def_id);
|
||||
|
||||
// This edge is actually implied by the call to
|
||||
// `lookup_trait_def`, but I'm trying to be future-proof. See
|
||||
@ -288,8 +292,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
|
||||
self.add_constraints_from_substs(generics,
|
||||
trait_ref.def_id,
|
||||
&trait_def.generics.types,
|
||||
&trait_def.generics.regions,
|
||||
&trait_generics.types,
|
||||
&trait_generics.regions,
|
||||
trait_ref.substs,
|
||||
variance);
|
||||
}
|
||||
@ -356,7 +360,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
|
||||
ty::TyProjection(ref data) => {
|
||||
let trait_ref = &data.trait_ref;
|
||||
let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id);
|
||||
let trait_generics = self.tcx().item_generics(trait_ref.def_id);
|
||||
|
||||
// This edge is actually implied by the call to
|
||||
// `lookup_trait_def`, but I'm trying to be future-proof. See
|
||||
@ -365,8 +369,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
|
||||
self.add_constraints_from_substs(generics,
|
||||
trait_ref.def_id,
|
||||
&trait_def.generics.types,
|
||||
&trait_def.generics.regions,
|
||||
&trait_generics.types,
|
||||
&trait_generics.regions,
|
||||
trait_ref.substs,
|
||||
variance);
|
||||
}
|
||||
|
@ -151,14 +151,13 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
|
||||
}
|
||||
|
||||
pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
|
||||
let def = cx.tcx.lookup_trait_def(did);
|
||||
let trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect();
|
||||
let predicates = cx.tcx.item_predicates(did);
|
||||
let generics = (def.generics, &predicates).clean(cx);
|
||||
let generics = (cx.tcx.item_generics(did), &predicates).clean(cx);
|
||||
let generics = filter_non_trait_generics(did, generics);
|
||||
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
|
||||
clean::Trait {
|
||||
unsafety: def.unsafety,
|
||||
unsafety: cx.tcx.lookup_trait_def(did).unsafety,
|
||||
generics: generics,
|
||||
items: trait_items,
|
||||
bounds: supertrait_bounds,
|
||||
|
@ -1407,9 +1407,8 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
||||
// are actually located on the trait/impl itself, so we need to load
|
||||
// all of the generics from there and then look for bounds that are
|
||||
// applied to this associated type in question.
|
||||
let def = cx.tcx.lookup_trait_def(did);
|
||||
let predicates = cx.tcx.item_predicates(did);
|
||||
let generics = (def.generics, &predicates).clean(cx);
|
||||
let generics = (cx.tcx.item_generics(did), &predicates).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