Auto merge of #38053 - eddyb:lazy-9, r=nikomatsakis
[9/n] rustc: move type information out of AdtDef and TraitDef. _This is part of a series ([prev](https://github.com/rust-lang/rust/pull/37688) | [next]()) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well. If any motivation is unclear, please ask for additional PR description clarifications or code comments._ <hr> Both `AdtDef` and `TraitDef` contained type information (field types, generics and predicates) which was required to create them, preventing their use before that type information exists, or in the case of field types, *mutation* was required, leading to a variance-magicking implementation of `ivar`s. This PR takes that information out and the resulting cleaner setup could even eventually end up merged with HIR, because, just like `AssociatedItem` before it, there's no dependency on types anymore. (With one exception, variant discriminants should probably be moved into their own map later.)
This commit is contained in:
commit
c80c31a502
|
@ -110,7 +110,6 @@ pub enum DepNode<D: Clone + Debug> {
|
||||||
// predicates for an item wind up in `ItemSignature`).
|
// predicates for an item wind up in `ItemSignature`).
|
||||||
AssociatedItems(D),
|
AssociatedItems(D),
|
||||||
ItemSignature(D),
|
ItemSignature(D),
|
||||||
FieldTy(D),
|
|
||||||
SizedConstraint(D),
|
SizedConstraint(D),
|
||||||
AssociatedItemDefIds(D),
|
AssociatedItemDefIds(D),
|
||||||
InherentImpls(D),
|
InherentImpls(D),
|
||||||
|
@ -161,7 +160,6 @@ impl<D: Clone + Debug> DepNode<D> {
|
||||||
TypeckItemBody,
|
TypeckItemBody,
|
||||||
AssociatedItems,
|
AssociatedItems,
|
||||||
ItemSignature,
|
ItemSignature,
|
||||||
FieldTy,
|
|
||||||
AssociatedItemDefIds,
|
AssociatedItemDefIds,
|
||||||
InherentImpls,
|
InherentImpls,
|
||||||
TraitImpls,
|
TraitImpls,
|
||||||
|
@ -229,7 +227,6 @@ impl<D: Clone + Debug> DepNode<D> {
|
||||||
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
|
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
|
||||||
AssociatedItems(ref d) => op(d).map(AssociatedItems),
|
AssociatedItems(ref d) => op(d).map(AssociatedItems),
|
||||||
ItemSignature(ref d) => op(d).map(ItemSignature),
|
ItemSignature(ref d) => op(d).map(ItemSignature),
|
||||||
FieldTy(ref d) => op(d).map(FieldTy),
|
|
||||||
SizedConstraint(ref d) => op(d).map(SizedConstraint),
|
SizedConstraint(ref d) => op(d).map(SizedConstraint),
|
||||||
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
|
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
|
||||||
InherentImpls(ref d) => op(d).map(InherentImpls),
|
InherentImpls(ref d) => op(d).map(InherentImpls),
|
||||||
|
|
|
@ -278,8 +278,8 @@ pub trait CrateStore<'tcx> {
|
||||||
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||||
-> ty::Generics<'tcx>;
|
-> ty::Generics<'tcx>;
|
||||||
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
|
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 adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef;
|
||||||
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
|
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
|
||||||
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
|
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
|
||||||
|
|
||||||
|
@ -425,9 +425,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
|
||||||
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||||
-> ty::Generics<'tcx> { bug!("item_generics") }
|
-> ty::Generics<'tcx> { bug!("item_generics") }
|
||||||
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
|
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") }
|
{ bug!("trait_def") }
|
||||||
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
|
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef
|
||||||
{ bug!("adt_def") }
|
{ bug!("adt_def") }
|
||||||
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
|
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
|
||||||
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
|
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
|
||||||
|
|
|
@ -701,7 +701,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
// are properly handled.
|
// are properly handled.
|
||||||
self.walk_expr(with_expr);
|
self.walk_expr(with_expr);
|
||||||
|
|
||||||
fn contains_field_named(field: ty::FieldDef,
|
fn contains_field_named(field: &ty::FieldDef,
|
||||||
fields: &[hir::Field])
|
fields: &[hir::Field])
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
|
|
|
@ -462,7 +462,7 @@ pub enum TerminatorKind<'tcx> {
|
||||||
/// lvalue evaluates to some enum; jump depending on the branch
|
/// lvalue evaluates to some enum; jump depending on the branch
|
||||||
Switch {
|
Switch {
|
||||||
discr: Lvalue<'tcx>,
|
discr: Lvalue<'tcx>,
|
||||||
adt_def: AdtDef<'tcx>,
|
adt_def: &'tcx AdtDef,
|
||||||
targets: Vec<BasicBlock>,
|
targets: Vec<BasicBlock>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -866,7 +866,7 @@ pub enum ProjectionElem<'tcx, V> {
|
||||||
/// "Downcast" to a variant of an ADT. Currently, we only introduce
|
/// "Downcast" to a variant of an ADT. Currently, we only introduce
|
||||||
/// this for ADTs with more than one variant. It may be better to
|
/// this for ADTs with more than one variant. It may be better to
|
||||||
/// just introduce it always, or always for enums.
|
/// just introduce it always, or always for enums.
|
||||||
Downcast(AdtDef<'tcx>, usize),
|
Downcast(&'tcx AdtDef, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Alias for projections as they appear in lvalues, where the base is an lvalue
|
/// Alias for projections as they appear in lvalues, where the base is an lvalue
|
||||||
|
@ -1035,7 +1035,7 @@ pub enum AggregateKind<'tcx> {
|
||||||
/// The second field is variant number (discriminant), it's equal to 0
|
/// The second field is variant number (discriminant), it's equal to 0
|
||||||
/// for struct and union expressions. The fourth field is active field
|
/// for struct and union expressions. The fourth field is active field
|
||||||
/// number and is present only for union expressions.
|
/// number and is present only for union expressions.
|
||||||
Adt(AdtDef<'tcx>, usize, &'tcx Substs<'tcx>, Option<usize>),
|
Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<usize>),
|
||||||
Closure(DefId, ClosureSubsts<'tcx>),
|
Closure(DefId, ClosureSubsts<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub enum LvalueTy<'tcx> {
|
||||||
Ty { ty: Ty<'tcx> },
|
Ty { ty: Ty<'tcx> },
|
||||||
|
|
||||||
/// Downcast to a particular variant of an enum.
|
/// Downcast to a particular variant of an enum.
|
||||||
Downcast { adt_def: AdtDef<'tcx>,
|
Downcast { adt_def: &'tcx AdtDef,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
variant_index: usize },
|
variant_index: usize },
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,11 +244,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
for item in self.tcx.get_attrs(def_id).iter() {
|
for item in self.tcx.get_attrs(def_id).iter() {
|
||||||
if item.check_name("rustc_on_unimplemented") {
|
if item.check_name("rustc_on_unimplemented") {
|
||||||
let err_sp = item.meta().span.substitute_dummy(span);
|
let err_sp = item.meta().span.substitute_dummy(span);
|
||||||
let def = self.tcx.lookup_trait_def(trait_ref.def_id);
|
let trait_str = self.tcx.item_path_str(trait_ref.def_id);
|
||||||
let trait_str = def.trait_ref.to_string();
|
|
||||||
if let Some(istring) = item.value_str() {
|
if let Some(istring) = item.value_str() {
|
||||||
let istring = &*istring.as_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(),
|
(param.name.as_str().to_string(),
|
||||||
trait_ref.substs.type_for_def(param).to_string())
|
trait_ref.substs.type_for_def(param).to_string())
|
||||||
}).collect::<FxHashMap<String, String>>();
|
}).collect::<FxHashMap<String, String>>();
|
||||||
|
|
|
@ -21,7 +21,8 @@ use super::elaborate_predicates;
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use traits;
|
use traits;
|
||||||
use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
|
use ty::subst::Substs;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[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 {
|
fn supertraits_reference_self(self, trait_def_id: DefId) -> bool {
|
||||||
let trait_def = self.lookup_trait_def(trait_def_id);
|
let trait_ref = ty::Binder(ty::TraitRef {
|
||||||
let trait_ref = trait_def.trait_ref.clone();
|
def_id: trait_def_id,
|
||||||
let trait_ref = trait_ref.to_poly_trait_ref();
|
substs: Substs::identity_for_item(self, trait_def_id)
|
||||||
|
});
|
||||||
let predicates = self.item_super_predicates(trait_def_id);
|
let predicates = self.item_super_predicates(trait_def_id);
|
||||||
predicates
|
predicates
|
||||||
.predicates
|
.predicates
|
||||||
|
@ -317,8 +319,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Compute supertraits of current trait lazily.
|
// Compute supertraits of current trait lazily.
|
||||||
if supertraits.is_none() {
|
if supertraits.is_none() {
|
||||||
let trait_def = self.lookup_trait_def(trait_def_id);
|
let trait_ref = ty::Binder(ty::TraitRef {
|
||||||
let trait_ref = ty::Binder(trait_def.trait_ref.clone());
|
def_id: trait_def_id,
|
||||||
|
substs: Substs::identity_for_item(self, trait_def_id)
|
||||||
|
});
|
||||||
supertraits = Some(traits::supertraits(self, trait_ref).collect());
|
supertraits = Some(traits::supertraits(self, trait_ref).collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2544,7 +2544,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
(&ty::TyAdt(def, substs_a), &ty::TyAdt(_, substs_b)) => {
|
(&ty::TyAdt(def, substs_a), &ty::TyAdt(_, substs_b)) => {
|
||||||
let fields = def
|
let fields = def
|
||||||
.all_fields()
|
.all_fields()
|
||||||
.map(|f| f.unsubst_ty())
|
.map(|f| tcx.item_type(f.did))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// The last field of the structure has to exist and contain type parameters.
|
// The last field of the structure has to exist and contain type parameters.
|
||||||
|
|
|
@ -297,18 +297,18 @@ impl<'a, 'gcx, 'tcx> Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Ancestors<'a, 'tcx: 'a> {
|
pub struct Ancestors<'a> {
|
||||||
trait_def: &'a TraitDef<'tcx>,
|
trait_def: &'a TraitDef,
|
||||||
current_source: Option<Node>,
|
current_source: Option<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Iterator for Ancestors<'a, 'tcx> {
|
impl<'a> Iterator for Ancestors<'a> {
|
||||||
type Item = Node;
|
type Item = Node;
|
||||||
fn next(&mut self) -> Option<Node> {
|
fn next(&mut self) -> Option<Node> {
|
||||||
let cur = self.current_source.take();
|
let cur = self.current_source.take();
|
||||||
if let Some(Node::Impl(cur_impl)) = cur {
|
if let Some(Node::Impl(cur_impl)) = cur {
|
||||||
let parent = self.trait_def.specialization_graph.borrow().parent(cur_impl);
|
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));
|
self.current_source = Some(Node::Trait(parent));
|
||||||
} else {
|
} else {
|
||||||
self.current_source = Some(Node::Impl(parent));
|
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
|
/// Search the items from the given ancestors, returning each definition
|
||||||
/// with the given name and the given kind.
|
/// with the given name and the given kind.
|
||||||
#[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
|
#[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
|
/// Walk up the specialization ancestors of a given impl, starting with that
|
||||||
/// impl itself.
|
/// impl itself.
|
||||||
pub fn ancestors<'a, 'tcx>(trait_def: &'a TraitDef<'tcx>,
|
pub fn ancestors<'a>(trait_def: &'a TraitDef, start_from_impl: DefId) -> Ancestors<'a> {
|
||||||
start_from_impl: DefId)
|
|
||||||
-> Ancestors<'a, 'tcx> {
|
|
||||||
Ancestors {
|
Ancestors {
|
||||||
trait_def: trait_def,
|
trait_def: trait_def,
|
||||||
current_source: Some(Node::Impl(start_from_impl)),
|
current_source: Some(Node::Impl(start_from_impl)),
|
||||||
|
|
|
@ -68,8 +68,8 @@ pub struct CtxtArenas<'tcx> {
|
||||||
|
|
||||||
// references
|
// references
|
||||||
generics: TypedArena<ty::Generics<'tcx>>,
|
generics: TypedArena<ty::Generics<'tcx>>,
|
||||||
trait_def: TypedArena<ty::TraitDef<'tcx>>,
|
trait_def: TypedArena<ty::TraitDef>,
|
||||||
adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
|
adt_def: TypedArena<ty::AdtDef>,
|
||||||
mir: TypedArena<RefCell<Mir<'tcx>>>,
|
mir: TypedArena<RefCell<Mir<'tcx>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,6 +425,7 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
pub impl_trait_refs: RefCell<DepTrackingMap<maps::ImplTraitRefs<'tcx>>>,
|
pub impl_trait_refs: RefCell<DepTrackingMap<maps::ImplTraitRefs<'tcx>>>,
|
||||||
pub trait_defs: RefCell<DepTrackingMap<maps::TraitDefs<'tcx>>>,
|
pub trait_defs: RefCell<DepTrackingMap<maps::TraitDefs<'tcx>>>,
|
||||||
pub adt_defs: RefCell<DepTrackingMap<maps::AdtDefs<'tcx>>>,
|
pub adt_defs: RefCell<DepTrackingMap<maps::AdtDefs<'tcx>>>,
|
||||||
|
pub adt_sized_constraint: RefCell<DepTrackingMap<maps::AdtSizedConstraint<'tcx>>>,
|
||||||
|
|
||||||
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
|
/// Maps from the def-id of an item (trait/struct/enum/fn) to its
|
||||||
/// associated generics and predicates.
|
/// associated generics and predicates.
|
||||||
|
@ -688,38 +689,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.global_interners.arenas.mir.alloc(RefCell::new(mir))
|
self.global_interners.arenas.mir.alloc(RefCell::new(mir))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
|
pub fn alloc_trait_def(self, def: ty::TraitDef) -> &'gcx ty::TraitDef {
|
||||||
-> &'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> {
|
|
||||||
self.global_interners.arenas.trait_def.alloc(def)
|
self.global_interners.arenas.trait_def.alloc(def)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
|
pub fn alloc_adt_def(self,
|
||||||
// this will need a transmute when reverse-variance is removed
|
did: DefId,
|
||||||
if let Some(prev) = self.adt_defs.borrow_mut().insert(did, adt_def) {
|
kind: AdtKind,
|
||||||
bug!("Tried to overwrite interned AdtDef: {:?}", prev)
|
variants: Vec<ty::VariantDef>)
|
||||||
}
|
-> &'gcx ty::AdtDef {
|
||||||
}
|
let def = ty::AdtDef::new(self, did, kind, variants);
|
||||||
|
self.global_interners.arenas.adt_def.alloc(def)
|
||||||
pub fn intern_adt_def(self,
|
|
||||||
did: DefId,
|
|
||||||
kind: AdtKind,
|
|
||||||
variants: Vec<ty::VariantDefData<'gcx, 'gcx>>)
|
|
||||||
-> ty::AdtDefMaster<'gcx> {
|
|
||||||
let def = ty::AdtDefData::new(self, did, kind, variants);
|
|
||||||
let interned = self.global_interners.arenas.adt_def.alloc(def);
|
|
||||||
self.insert_adt_def(did, interned);
|
|
||||||
interned
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
|
pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
|
||||||
|
@ -815,6 +795,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
impl_trait_refs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
impl_trait_refs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||||
trait_defs: 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())),
|
adt_defs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||||
|
adt_sized_constraint: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||||
generics: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
generics: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||||
predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||||
super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||||
|
@ -1392,7 +1373,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str())
|
self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_adt(self, def: AdtDef<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
|
pub fn mk_adt(self, def: &'tcx AdtDef, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
|
||||||
// take a copy of substs so that we own the vectors inside
|
// take a copy of substs so that we own the vectors inside
|
||||||
self.mk_ty(TyAdt(def, substs))
|
self.mk_ty(TyAdt(def, substs))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use dep_graph::DepNode;
|
|
||||||
use hir::def_id::DefId;
|
|
||||||
use ty::{Ty, TyS};
|
|
||||||
use ty::tls;
|
|
||||||
|
|
||||||
use rustc_data_structures::ivar;
|
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use core::nonzero::NonZero;
|
|
||||||
|
|
||||||
/// An IVar that contains a Ty. 'lt is a (reverse-variant) upper bound
|
|
||||||
/// on the lifetime of the IVar. This is required because of variance
|
|
||||||
/// problems: the IVar needs to be variant with respect to 'tcx (so
|
|
||||||
/// it can be referred to from Ty) but can only be modified if its
|
|
||||||
/// lifetime is exactly 'tcx.
|
|
||||||
///
|
|
||||||
/// Safety invariants:
|
|
||||||
/// (A) self.0, if fulfilled, is a valid Ty<'tcx>
|
|
||||||
/// (B) no aliases to this value with a 'tcx longer than this
|
|
||||||
/// value's 'lt exist
|
|
||||||
///
|
|
||||||
/// Dependency tracking: each ivar does not know what node in the
|
|
||||||
/// dependency graph it is associated with, so when you get/fulfill
|
|
||||||
/// you must supply a `DepNode` id. This should always be the same id!
|
|
||||||
///
|
|
||||||
/// NonZero is used rather than Unique because Unique isn't Copy.
|
|
||||||
pub struct TyIVar<'tcx, 'lt: 'tcx>(ivar::Ivar<NonZero<*const TyS<'static>>>,
|
|
||||||
PhantomData<fn(TyS<'lt>)->TyS<'tcx>>);
|
|
||||||
|
|
||||||
impl<'tcx, 'lt> TyIVar<'tcx, 'lt> {
|
|
||||||
#[inline]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
// Invariant (A) satisfied because the IVar is unfulfilled
|
|
||||||
// Invariant (B) because 'lt : 'tcx
|
|
||||||
TyIVar(ivar::Ivar::new(), PhantomData)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get(&self, dep_node: DepNode<DefId>) -> Option<Ty<'tcx>> {
|
|
||||||
tls::with(|tcx| tcx.dep_graph.read(dep_node));
|
|
||||||
self.untracked_get()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads the ivar without registered a dep-graph read. Use with
|
|
||||||
/// caution.
|
|
||||||
#[inline]
|
|
||||||
pub fn untracked_get(&self) -> Option<Ty<'tcx>> {
|
|
||||||
match self.0.get() {
|
|
||||||
None => None,
|
|
||||||
// valid because of invariant (A)
|
|
||||||
Some(v) => Some(unsafe { &*(*v as *const TyS<'tcx>) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn unwrap(&self, dep_node: DepNode<DefId>) -> Ty<'tcx> {
|
|
||||||
self.get(dep_node).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fulfill(&self, dep_node: DepNode<DefId>, value: Ty<'lt>) {
|
|
||||||
tls::with(|tcx| tcx.dep_graph.write(dep_node));
|
|
||||||
|
|
||||||
// Invariant (A) is fulfilled, because by (B), every alias
|
|
||||||
// of this has a 'tcx longer than 'lt.
|
|
||||||
let value: *const TyS<'lt> = value;
|
|
||||||
// FIXME(27214): unneeded [as *const ()]
|
|
||||||
let value = value as *const () as *const TyS<'static>;
|
|
||||||
self.0.fulfill(unsafe { NonZero::new(value) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx, 'lt> fmt::Debug for TyIVar<'tcx, 'lt> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self.untracked_get() {
|
|
||||||
Some(val) => write!(f, "TyIVar({:?})", val),
|
|
||||||
None => f.write_str("TyIVar(<unfulfilled>)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -39,8 +39,9 @@ dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
|
||||||
dep_map_ty! { SuperPredicates: 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! { AssociatedItemDefIds: AssociatedItemDefIds(DefId) -> Rc<Vec<DefId>> }
|
||||||
dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>> }
|
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! { AdtDefs: ItemSignature(DefId) -> &'tcx ty::AdtDef }
|
||||||
|
dep_map_ty! { AdtSizedConstraint: SizedConstraint(DefId) -> Ty<'tcx> }
|
||||||
dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>> }
|
dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>> }
|
||||||
dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
|
dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
|
||||||
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
|
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
|
||||||
|
|
|
@ -93,7 +93,6 @@ pub mod util;
|
||||||
mod contents;
|
mod contents;
|
||||||
mod context;
|
mod context;
|
||||||
mod flags;
|
mod flags;
|
||||||
mod ivar;
|
|
||||||
mod structural_impls;
|
mod structural_impls;
|
||||||
mod sty;
|
mod sty;
|
||||||
|
|
||||||
|
@ -623,10 +622,6 @@ pub struct RegionParameterDef<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> 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 {
|
pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
|
||||||
ty::EarlyBoundRegion {
|
ty::EarlyBoundRegion {
|
||||||
index: self.index,
|
index: self.index,
|
||||||
|
@ -1313,106 +1308,64 @@ bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type AdtDef<'tcx> = &'tcx AdtDefData<'tcx, 'static>;
|
pub struct VariantDef {
|
||||||
pub type VariantDef<'tcx> = &'tcx VariantDefData<'tcx, 'static>;
|
|
||||||
pub type FieldDef<'tcx> = &'tcx FieldDefData<'tcx, 'static>;
|
|
||||||
|
|
||||||
// See comment on AdtDefData for explanation
|
|
||||||
pub type AdtDefMaster<'tcx> = &'tcx AdtDefData<'tcx, 'tcx>;
|
|
||||||
pub type VariantDefMaster<'tcx> = &'tcx VariantDefData<'tcx, 'tcx>;
|
|
||||||
pub type FieldDefMaster<'tcx> = &'tcx FieldDefData<'tcx, 'tcx>;
|
|
||||||
|
|
||||||
pub struct VariantDefData<'tcx, 'container: 'tcx> {
|
|
||||||
/// The variant's DefId. If this is a tuple-like struct,
|
/// The variant's DefId. If this is a tuple-like struct,
|
||||||
/// this is the DefId of the struct's ctor.
|
/// this is the DefId of the struct's ctor.
|
||||||
pub did: DefId,
|
pub did: DefId,
|
||||||
pub name: Name, // struct's name if this is a struct
|
pub name: Name, // struct's name if this is a struct
|
||||||
pub disr_val: Disr,
|
pub disr_val: Disr,
|
||||||
pub fields: Vec<FieldDefData<'tcx, 'container>>,
|
pub fields: Vec<FieldDef>,
|
||||||
pub ctor_kind: CtorKind,
|
pub ctor_kind: CtorKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FieldDefData<'tcx, 'container: 'tcx> {
|
pub struct FieldDef {
|
||||||
pub did: DefId,
|
pub did: DefId,
|
||||||
pub name: Name,
|
pub name: Name,
|
||||||
pub vis: Visibility,
|
pub vis: Visibility,
|
||||||
/// TyIVar is used here to allow for variance (see the doc at
|
|
||||||
/// AdtDefData).
|
|
||||||
///
|
|
||||||
/// Note: direct accesses to `ty` must also add dep edges.
|
|
||||||
ty: ivar::TyIVar<'tcx, 'container>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The definition of an abstract data type - a struct or enum.
|
/// The definition of an abstract data type - a struct or enum.
|
||||||
///
|
///
|
||||||
/// These are all interned (by intern_adt_def) into the adt_defs
|
/// These are all interned (by intern_adt_def) into the adt_defs
|
||||||
/// table.
|
/// table.
|
||||||
///
|
pub struct AdtDef {
|
||||||
/// Because of the possibility of nested tcx-s, this type
|
|
||||||
/// needs 2 lifetimes: the traditional variant lifetime ('tcx)
|
|
||||||
/// bounding the lifetime of the inner types is of course necessary.
|
|
||||||
/// However, it is not sufficient - types from a child tcx must
|
|
||||||
/// not be leaked into the master tcx by being stored in an AdtDefData.
|
|
||||||
///
|
|
||||||
/// The 'container lifetime ensures that by outliving the container
|
|
||||||
/// tcx and preventing shorter-lived types from being inserted. When
|
|
||||||
/// write access is not needed, the 'container lifetime can be
|
|
||||||
/// erased to 'static, which can be done by the AdtDef wrapper.
|
|
||||||
pub struct AdtDefData<'tcx, 'container: 'tcx> {
|
|
||||||
pub did: DefId,
|
pub did: DefId,
|
||||||
pub variants: Vec<VariantDefData<'tcx, 'container>>,
|
pub variants: Vec<VariantDef>,
|
||||||
destructor: Cell<Option<DefId>>,
|
destructor: Cell<Option<DefId>>,
|
||||||
flags: Cell<AdtFlags>,
|
flags: Cell<AdtFlags>
|
||||||
sized_constraint: ivar::TyIVar<'tcx, 'container>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, 'container> PartialEq for AdtDefData<'tcx, 'container> {
|
impl PartialEq for AdtDef {
|
||||||
// AdtDefData are always interned and this is part of TyS equality
|
// AdtDef are always interned and this is part of TyS equality
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
|
fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, 'container> Eq for AdtDefData<'tcx, 'container> {}
|
impl Eq for AdtDef {}
|
||||||
|
|
||||||
impl<'tcx, 'container> Hash for AdtDefData<'tcx, 'container> {
|
impl Hash for AdtDef {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash<H: Hasher>(&self, s: &mut H) {
|
fn hash<H: Hasher>(&self, s: &mut H) {
|
||||||
(self as *const AdtDefData).hash(s)
|
(self as *const AdtDef).hash(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> serialize::UseSpecializedEncodable for AdtDef<'tcx> {
|
impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef {
|
||||||
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
self.did.encode(s)
|
self.did.encode(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> serialize::UseSpecializedDecodable for AdtDef<'tcx> {}
|
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> AdtDefData<'tcx, 'static> {
|
|
||||||
#[inline]
|
|
||||||
pub fn is_uninhabited_recurse(&'tcx self,
|
|
||||||
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
|
|
||||||
block: Option<NodeId>,
|
|
||||||
cx: TyCtxt<'a, 'gcx, 'tcx>,
|
|
||||||
substs: &'tcx Substs<'tcx>) -> bool {
|
|
||||||
if !visited.insert((self.did, substs)) {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
self.variants.iter().all(|v| {
|
|
||||||
v.is_uninhabited_recurse(visited, block, cx, substs, self.is_union())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum AdtKind { Struct, Union, Enum }
|
pub enum AdtKind { Struct, Union, Enum }
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
did: DefId,
|
did: DefId,
|
||||||
kind: AdtKind,
|
kind: AdtKind,
|
||||||
variants: Vec<VariantDefData<'gcx, 'container>>) -> Self {
|
variants: Vec<VariantDef>) -> Self {
|
||||||
let mut flags = AdtFlags::NO_ADT_FLAGS;
|
let mut flags = AdtFlags::NO_ADT_FLAGS;
|
||||||
let attrs = tcx.get_attrs(did);
|
let attrs = tcx.get_attrs(did);
|
||||||
if attr::contains_name(&attrs, "fundamental") {
|
if attr::contains_name(&attrs, "fundamental") {
|
||||||
|
@ -1429,12 +1382,11 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
||||||
AdtKind::Union => flags = flags | AdtFlags::IS_UNION,
|
AdtKind::Union => flags = flags | AdtFlags::IS_UNION,
|
||||||
AdtKind::Struct => {}
|
AdtKind::Struct => {}
|
||||||
}
|
}
|
||||||
AdtDefData {
|
AdtDef {
|
||||||
did: did,
|
did: did,
|
||||||
variants: variants,
|
variants: variants,
|
||||||
flags: Cell::new(flags),
|
flags: Cell::new(flags),
|
||||||
destructor: Cell::new(None),
|
destructor: Cell::new(None),
|
||||||
sized_constraint: ivar::TyIVar::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,6 +1397,20 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
||||||
self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
|
self.flags.set(self.flags.get() | AdtFlags::IS_DTORCK_VALID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_uninhabited_recurse(&self,
|
||||||
|
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
|
||||||
|
block: Option<NodeId>,
|
||||||
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
substs: &'tcx Substs<'tcx>) -> bool {
|
||||||
|
if !visited.insert((self.did, substs)) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
self.variants.iter().all(|v| {
|
||||||
|
v.is_uninhabited_recurse(visited, block, tcx, substs, self.is_union())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_struct(&self) -> bool {
|
pub fn is_struct(&self) -> bool {
|
||||||
!self.is_union() && !self.is_enum()
|
!self.is_union() && !self.is_enum()
|
||||||
|
@ -1524,7 +1490,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
||||||
|
|
||||||
/// Asserts this is a struct and returns the struct's unique
|
/// Asserts this is a struct and returns the struct's unique
|
||||||
/// variant.
|
/// variant.
|
||||||
pub fn struct_variant(&self) -> &VariantDefData<'gcx, 'container> {
|
pub fn struct_variant(&self) -> &VariantDef {
|
||||||
assert!(!self.is_enum());
|
assert!(!self.is_enum());
|
||||||
&self.variants[0]
|
&self.variants[0]
|
||||||
}
|
}
|
||||||
|
@ -1537,14 +1503,8 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
||||||
/// Returns an iterator over all fields contained
|
/// Returns an iterator over all fields contained
|
||||||
/// by this ADT.
|
/// by this ADT.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn all_fields(&self) ->
|
pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> {
|
||||||
iter::FlatMap<
|
self.variants.iter().flat_map(|v| v.fields.iter())
|
||||||
slice::Iter<VariantDefData<'gcx, 'container>>,
|
|
||||||
slice::Iter<FieldDefData<'gcx, 'container>>,
|
|
||||||
for<'s> fn(&'s VariantDefData<'gcx, 'container>)
|
|
||||||
-> slice::Iter<'s, FieldDefData<'gcx, 'container>>
|
|
||||||
> {
|
|
||||||
self.variants.iter().flat_map(VariantDefData::fields_iter)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1557,7 +1517,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
||||||
self.variants.iter().all(|v| v.fields.is_empty())
|
self.variants.iter().all(|v| v.fields.is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variant_with_id(&self, vid: DefId) -> &VariantDefData<'gcx, 'container> {
|
pub fn variant_with_id(&self, vid: DefId) -> &VariantDef {
|
||||||
self.variants
|
self.variants
|
||||||
.iter()
|
.iter()
|
||||||
.find(|v| v.did == vid)
|
.find(|v| v.did == vid)
|
||||||
|
@ -1571,7 +1531,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
||||||
.expect("variant_index_with_id: unknown variant")
|
.expect("variant_index_with_id: unknown variant")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variant_of_def(&self, def: Def) -> &VariantDefData<'gcx, 'container> {
|
pub fn variant_of_def(&self, def: Def) -> &VariantDef {
|
||||||
match def {
|
match def {
|
||||||
Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
|
Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
|
||||||
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
|
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
|
||||||
|
@ -1594,9 +1554,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
|
||||||
None => NoDtor,
|
None => NoDtor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'tcx, 'container> {
|
|
||||||
/// Returns a simpler type such that `Self: Sized` if and only
|
/// Returns a simpler type such that `Self: Sized` if and only
|
||||||
/// if that type is Sized, or `TyErr` if this type is recursive.
|
/// if that type is Sized, or `TyErr` if this type is recursive.
|
||||||
///
|
///
|
||||||
|
@ -1615,19 +1573,9 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'tcx, 'container> {
|
||||||
/// Due to normalization being eager, this applies even if
|
/// Due to normalization being eager, this applies even if
|
||||||
/// the associated type is behind a pointer, e.g. issue #31299.
|
/// the associated type is behind a pointer, e.g. issue #31299.
|
||||||
pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
|
pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
|
||||||
match self.sized_constraint.get(DepNode::SizedConstraint(self.did)) {
|
self.calculate_sized_constraint_inner(tcx.global_tcx(), &mut Vec::new())
|
||||||
None => {
|
|
||||||
let global_tcx = tcx.global_tcx();
|
|
||||||
let this = global_tcx.lookup_adt_def_master(self.did);
|
|
||||||
this.calculate_sized_constraint_inner(global_tcx, &mut Vec::new());
|
|
||||||
self.sized_constraint(tcx)
|
|
||||||
}
|
|
||||||
Some(ty) => ty
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
|
|
||||||
/// Calculates the Sized-constraint.
|
/// Calculates the Sized-constraint.
|
||||||
///
|
///
|
||||||
/// As the Sized-constraint of enums can be a *set* of types,
|
/// As the Sized-constraint of enums can be a *set* of types,
|
||||||
|
@ -1643,42 +1591,41 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
|
||||||
/// such.
|
/// such.
|
||||||
/// - a TyError, if a type contained itself. The representability
|
/// - a TyError, if a type contained itself. The representability
|
||||||
/// check should catch this case.
|
/// check should catch this case.
|
||||||
fn calculate_sized_constraint_inner(&'tcx self,
|
fn calculate_sized_constraint_inner(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
stack: &mut Vec<AdtDefMaster<'tcx>>)
|
stack: &mut Vec<DefId>)
|
||||||
|
-> Ty<'tcx>
|
||||||
{
|
{
|
||||||
let dep_node = || DepNode::SizedConstraint(self.did);
|
if let Some(ty) = tcx.adt_sized_constraint.borrow().get(&self.did) {
|
||||||
|
return ty;
|
||||||
|
}
|
||||||
|
|
||||||
// Follow the memoization pattern: push the computation of
|
// Follow the memoization pattern: push the computation of
|
||||||
// DepNode::SizedConstraint as our current task.
|
// DepNode::SizedConstraint as our current task.
|
||||||
let _task = tcx.dep_graph.in_task(dep_node());
|
let _task = tcx.dep_graph.in_task(DepNode::SizedConstraint(self.did));
|
||||||
if self.sized_constraint.untracked_get().is_some() {
|
|
||||||
// ---------------
|
|
||||||
// can skip the dep-graph read since we just pushed the task
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if stack.contains(&self) {
|
if stack.contains(&self.did) {
|
||||||
debug!("calculate_sized_constraint: {:?} is recursive", self);
|
debug!("calculate_sized_constraint: {:?} is recursive", self);
|
||||||
// This should be reported as an error by `check_representable`.
|
// This should be reported as an error by `check_representable`.
|
||||||
//
|
//
|
||||||
// Consider the type as Sized in the meanwhile to avoid
|
// Consider the type as Sized in the meanwhile to avoid
|
||||||
// further errors.
|
// further errors.
|
||||||
self.sized_constraint.fulfill(dep_node(), tcx.types.err);
|
tcx.adt_sized_constraint.borrow_mut().insert(self.did, tcx.types.err);
|
||||||
return;
|
return tcx.types.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
stack.push(self);
|
stack.push(self.did);
|
||||||
|
|
||||||
let tys : Vec<_> =
|
let tys : Vec<_> =
|
||||||
self.variants.iter().flat_map(|v| {
|
self.variants.iter().flat_map(|v| {
|
||||||
v.fields.last()
|
v.fields.last()
|
||||||
}).flat_map(|f| {
|
}).flat_map(|f| {
|
||||||
self.sized_constraint_for_ty(tcx, stack, f.unsubst_ty())
|
let ty = tcx.item_type(f.did);
|
||||||
|
self.sized_constraint_for_ty(tcx, stack, ty)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let self_ = stack.pop().unwrap();
|
let self_ = stack.pop().unwrap();
|
||||||
assert_eq!(self_, self);
|
assert_eq!(self_, self.did);
|
||||||
|
|
||||||
let ty = match tys.len() {
|
let ty = match tys.len() {
|
||||||
_ if tys.references_error() => tcx.types.err,
|
_ if tys.references_error() => tcx.types.err,
|
||||||
|
@ -1687,24 +1634,26 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
|
||||||
_ => tcx.intern_tup(&tys[..])
|
_ => tcx.intern_tup(&tys[..])
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.sized_constraint.get(dep_node()) {
|
let old = tcx.adt_sized_constraint.borrow().get(&self.did).cloned();
|
||||||
|
match old {
|
||||||
Some(old_ty) => {
|
Some(old_ty) => {
|
||||||
debug!("calculate_sized_constraint: {:?} recurred", self);
|
debug!("calculate_sized_constraint: {:?} recurred", self);
|
||||||
assert_eq!(old_ty, tcx.types.err)
|
assert_eq!(old_ty, tcx.types.err);
|
||||||
|
old_ty
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
debug!("calculate_sized_constraint: {:?} => {:?}", self, ty);
|
debug!("calculate_sized_constraint: {:?} => {:?}", self, ty);
|
||||||
self.sized_constraint.fulfill(dep_node(), ty)
|
tcx.adt_sized_constraint.borrow_mut().insert(self.did, ty);
|
||||||
|
ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sized_constraint_for_ty(
|
fn sized_constraint_for_ty(&self,
|
||||||
&'tcx self,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
stack: &mut Vec<DefId>,
|
||||||
stack: &mut Vec<AdtDefMaster<'tcx>>,
|
ty: Ty<'tcx>)
|
||||||
ty: Ty<'tcx>
|
-> Vec<Ty<'tcx>> {
|
||||||
) -> Vec<Ty<'tcx>> {
|
|
||||||
let result = match ty.sty {
|
let result = match ty.sty {
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
||||||
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
||||||
|
@ -1726,12 +1675,9 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
|
||||||
|
|
||||||
TyAdt(adt, substs) => {
|
TyAdt(adt, substs) => {
|
||||||
// recursive case
|
// recursive case
|
||||||
let adt = tcx.lookup_adt_def_master(adt.did);
|
|
||||||
adt.calculate_sized_constraint_inner(tcx, stack);
|
|
||||||
let adt_ty =
|
let adt_ty =
|
||||||
adt.sized_constraint
|
adt.calculate_sized_constraint_inner(tcx, stack)
|
||||||
.unwrap(DepNode::SizedConstraint(adt.did))
|
.subst(tcx, substs);
|
||||||
.subst(tcx, substs);
|
|
||||||
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
|
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
|
||||||
ty, adt_ty);
|
ty, adt_ty);
|
||||||
if let ty::TyTuple(ref tys) = adt_ty.sty {
|
if let ty::TyTuple(ref tys) = adt_ty.sty {
|
||||||
|
@ -1780,16 +1726,11 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
|
impl<'a, 'gcx, 'tcx> VariantDef {
|
||||||
#[inline]
|
|
||||||
fn fields_iter(&self) -> slice::Iter<FieldDefData<'tcx, 'container>> {
|
|
||||||
self.fields.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn find_field_named(&self,
|
pub fn find_field_named(&self,
|
||||||
name: ast::Name)
|
name: ast::Name)
|
||||||
-> Option<&FieldDefData<'tcx, 'container>> {
|
-> Option<&FieldDef> {
|
||||||
self.fields.iter().find(|f| f.name == name)
|
self.fields.iter().find(|f| f.name == name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1801,55 +1742,32 @@ impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
|
pub fn field_named(&self, name: ast::Name) -> &FieldDef {
|
||||||
self.find_field_named(name).unwrap()
|
self.find_field_named(name).unwrap()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> VariantDefData<'tcx, 'static> {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_uninhabited_recurse(&'tcx self,
|
pub fn is_uninhabited_recurse(&self,
|
||||||
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
|
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
|
||||||
block: Option<NodeId>,
|
block: Option<NodeId>,
|
||||||
cx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
is_union: bool) -> bool {
|
is_union: bool) -> bool {
|
||||||
if is_union {
|
if is_union {
|
||||||
self.fields.iter().all(|f| f.is_uninhabited_recurse(visited, block, cx, substs))
|
self.fields.iter().all(|f| f.is_uninhabited_recurse(visited, block, tcx, substs))
|
||||||
} else {
|
} else {
|
||||||
self.fields.iter().any(|f| f.is_uninhabited_recurse(visited, block, cx, substs))
|
self.fields.iter().any(|f| f.is_uninhabited_recurse(visited, block, tcx, substs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx, 'container> FieldDefData<'tcx, 'container> {
|
impl<'a, 'gcx, 'tcx> FieldDef {
|
||||||
pub fn new(did: DefId,
|
|
||||||
name: Name,
|
|
||||||
vis: Visibility) -> Self {
|
|
||||||
FieldDefData {
|
|
||||||
did: did,
|
|
||||||
name: name,
|
|
||||||
vis: vis,
|
|
||||||
ty: ivar::TyIVar::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
|
pub fn ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, subst: &Substs<'tcx>) -> Ty<'tcx> {
|
||||||
self.unsubst_ty().subst(tcx, subst)
|
tcx.item_type(self.did).subst(tcx, subst)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unsubst_ty(&self) -> Ty<'tcx> {
|
|
||||||
self.ty.unwrap(DepNode::FieldTy(self.did))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fulfill_ty(&self, ty: Ty<'container>) {
|
|
||||||
self.ty.fulfill(DepNode::FieldTy(self.did), ty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> FieldDefData<'tcx, 'static> {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_uninhabited_recurse(&'tcx self,
|
pub fn is_uninhabited_recurse(&self,
|
||||||
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
|
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
|
||||||
block: Option<NodeId>,
|
block: Option<NodeId>,
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
@ -2295,7 +2213,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Returns `ty::VariantDef` if `def` refers to a struct,
|
// Returns `ty::VariantDef` if `def` refers to a struct,
|
||||||
// or variant or their constructors, panics otherwise.
|
// or variant or their constructors, panics otherwise.
|
||||||
pub fn expect_variant_def(self, def: Def) -> VariantDef<'tcx> {
|
pub fn expect_variant_def(self, def: Def) -> &'tcx VariantDef {
|
||||||
match def {
|
match def {
|
||||||
Def::Variant(did) | Def::VariantCtor(did, ..) => {
|
Def::Variant(did) | Def::VariantCtor(did, ..) => {
|
||||||
let enum_did = self.parent_def_id(did).unwrap();
|
let enum_did = self.parent_def_id(did).unwrap();
|
||||||
|
@ -2398,28 +2316,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the did of a trait, returns its canonical trait ref.
|
/// 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(
|
lookup_locally_or_in_crate_store(
|
||||||
"trait_defs", did, &self.trait_defs,
|
"trait_defs", did, &self.trait_defs,
|
||||||
|| self.alloc_trait_def(self.sess.cstore.trait_def(self.global_tcx(), did))
|
|| self.alloc_trait_def(self.sess.cstore.trait_def(self.global_tcx(), did))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the did of an ADT, return a master reference to its
|
/// Given the did of an ADT, return a reference to its definition.
|
||||||
/// definition. Unless you are planning on fulfilling the ADT's fields,
|
pub fn lookup_adt_def(self, did: DefId) -> &'gcx AdtDef {
|
||||||
/// use lookup_adt_def instead.
|
|
||||||
pub fn lookup_adt_def_master(self, did: DefId) -> AdtDefMaster<'gcx> {
|
|
||||||
lookup_locally_or_in_crate_store(
|
lookup_locally_or_in_crate_store(
|
||||||
"adt_defs", did, &self.adt_defs,
|
"adt_defs", did, &self.adt_defs,
|
||||||
|| self.sess.cstore.adt_def(self.global_tcx(), did)
|
|| self.sess.cstore.adt_def(self.global_tcx(), did))
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given the did of an ADT, return a reference to its definition.
|
|
||||||
pub fn lookup_adt_def(self, did: DefId) -> AdtDef<'gcx> {
|
|
||||||
// when reverse-variance goes away, a transmute::<AdtDefMaster,AdtDef>
|
|
||||||
// would be needed here.
|
|
||||||
self.lookup_adt_def_master(did)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the did of an item, returns its generics.
|
/// Given the did of an item, returns its generics.
|
||||||
|
|
|
@ -113,7 +113,7 @@ pub enum TypeVariants<'tcx> {
|
||||||
/// That is, even after substitution it is possible that there are type
|
/// That is, even after substitution it is possible that there are type
|
||||||
/// variables. This happens when the `TyAdt` corresponds to an ADT
|
/// variables. This happens when the `TyAdt` corresponds to an ADT
|
||||||
/// definition and not a concrete use of it.
|
/// definition and not a concrete use of it.
|
||||||
TyAdt(AdtDef<'tcx>, &'tcx Substs<'tcx>),
|
TyAdt(&'tcx AdtDef, &'tcx Substs<'tcx>),
|
||||||
|
|
||||||
/// `Box<T>`; this is nominally a struct in the documentation, but is
|
/// `Box<T>`; this is nominally a struct in the documentation, but is
|
||||||
/// special-cased internally. For example, it is possible to implicitly
|
/// special-cased internally. For example, it is possible to implicitly
|
||||||
|
@ -1267,7 +1267,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ty_adt_def(&self) -> Option<AdtDef<'tcx>> {
|
pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
TyAdt(adt, _) => Some(adt),
|
TyAdt(adt, _) => Some(adt),
|
||||||
_ => None
|
_ => None
|
||||||
|
|
|
@ -165,6 +165,14 @@ impl<'tcx> Decodable for Kind<'tcx> {
|
||||||
pub type Substs<'tcx> = Slice<Kind<'tcx>>;
|
pub type Substs<'tcx> = Slice<Kind<'tcx>>;
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||||
|
/// 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,
|
/// Creates a Substs for generic parameter definitions,
|
||||||
/// by calling closures to obtain each region and type.
|
/// by calling closures to obtain each region and type.
|
||||||
/// The closures get to observe the Substs as they're
|
/// The closures get to observe the Substs as they're
|
||||||
|
|
|
@ -19,7 +19,9 @@ use hir;
|
||||||
use util::nodemap::FxHashMap;
|
use util::nodemap::FxHashMap;
|
||||||
|
|
||||||
/// A trait's definition with type information.
|
/// A trait's definition with type information.
|
||||||
pub struct TraitDef<'tcx> {
|
pub struct TraitDef {
|
||||||
|
pub def_id: DefId,
|
||||||
|
|
||||||
pub unsafety: hir::Unsafety,
|
pub unsafety: hir::Unsafety,
|
||||||
|
|
||||||
/// If `true`, then this trait had the `#[rustc_paren_sugar]`
|
/// 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).
|
/// be usable with the sugar (or without it).
|
||||||
pub paren_sugar: bool,
|
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
|
// 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`
|
// simplified version of their `Self` type: impls with a simplifiable `Self`
|
||||||
// are stored in `nonblanket_impls` keyed by it, while all other impls are
|
// 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,
|
pub def_path_hash: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
impl<'a, 'gcx, 'tcx> TraitDef {
|
||||||
pub fn new(unsafety: hir::Unsafety,
|
pub fn new(def_id: DefId,
|
||||||
|
unsafety: hir::Unsafety,
|
||||||
paren_sugar: bool,
|
paren_sugar: bool,
|
||||||
generics: &'tcx ty::Generics<'tcx>,
|
|
||||||
trait_ref: ty::TraitRef<'tcx>,
|
|
||||||
def_path_hash: u64)
|
def_path_hash: u64)
|
||||||
-> TraitDef<'tcx> {
|
-> TraitDef {
|
||||||
TraitDef {
|
TraitDef {
|
||||||
|
def_id: def_id,
|
||||||
paren_sugar: paren_sugar,
|
paren_sugar: paren_sugar,
|
||||||
unsafety: unsafety,
|
unsafety: unsafety,
|
||||||
generics: generics,
|
|
||||||
trait_ref: trait_ref,
|
|
||||||
nonblanket_impls: RefCell::new(FxHashMap()),
|
nonblanket_impls: RefCell::new(FxHashMap()),
|
||||||
blanket_impls: RefCell::new(vec![]),
|
blanket_impls: RefCell::new(vec![]),
|
||||||
flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS),
|
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
|
// returns None if not yet calculated
|
||||||
pub fn object_safety(&self) -> Option<bool> {
|
pub fn object_safety(&self) -> Option<bool> {
|
||||||
if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
|
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>) {
|
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>) {
|
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.
|
/// Records a basic trait-to-implementation mapping.
|
||||||
|
@ -203,13 +190,13 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||||
.insert(tcx, impl_def_id)
|
.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)
|
specialization_graph::ancestors(self, of_impl)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, mut f: F) {
|
pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, mut f: F) {
|
||||||
self.read_trait_impls(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() {
|
for &impl_def_id in self.blanket_impls.borrow().iter() {
|
||||||
f(impl_def_id);
|
f(impl_def_id);
|
||||||
|
@ -231,7 +218,7 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||||
{
|
{
|
||||||
self.read_trait_impls(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() {
|
for &impl_def_id in self.blanket_impls.borrow().iter() {
|
||||||
f(impl_def_id);
|
f(impl_def_id);
|
||||||
|
|
|
@ -366,7 +366,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
/// `adt` that do not strictly outlive the adt value itself.
|
/// `adt` that do not strictly outlive the adt value itself.
|
||||||
/// (This allows programs to make cyclic structures without
|
/// (This allows programs to make cyclic structures without
|
||||||
/// resorting to unasfe means; see RFCs 769 and 1238).
|
/// resorting to unasfe means; see RFCs 769 and 1238).
|
||||||
pub fn is_adt_dtorck(self, adt: ty::AdtDef) -> bool {
|
pub fn is_adt_dtorck(self, adt: &ty::AdtDef) -> bool {
|
||||||
let dtor_method = match adt.destructor() {
|
let dtor_method = match adt.destructor() {
|
||||||
Some(dtor) => dtor,
|
Some(dtor) => dtor,
|
||||||
None => return false
|
None => return false
|
||||||
|
@ -773,7 +773,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
|
fn same_struct_or_enum<'tcx>(ty: Ty<'tcx>, def: &'tcx ty::AdtDef) -> bool {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
TyAdt(ty_def, _) => {
|
TyAdt(ty_def, _) => {
|
||||||
ty_def == def
|
ty_def == def
|
||||||
|
|
|
@ -388,14 +388,15 @@ 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 {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
|
ty::tls::with(|tcx| {
|
||||||
self.generics, self.trait_ref)
|
write!(f, "{}", tcx.item_path_str(self.def_id))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
|
impl fmt::Debug for ty::AdtDef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
ty::tls::with(|tcx| {
|
ty::tls::with(|tcx| {
|
||||||
write!(f, "{}", tcx.item_path_str(self.did))
|
write!(f, "{}", tcx.item_path_str(self.did))
|
||||||
|
|
|
@ -442,7 +442,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
fn move_paths_for_fields(&self,
|
fn move_paths_for_fields(&self,
|
||||||
base_lv: &Lvalue<'tcx>,
|
base_lv: &Lvalue<'tcx>,
|
||||||
variant_path: MovePathIndex,
|
variant_path: MovePathIndex,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
substs: &'tcx Substs<'tcx>)
|
substs: &'tcx Substs<'tcx>)
|
||||||
-> Vec<(Lvalue<'tcx>, Option<MovePathIndex>)>
|
-> Vec<(Lvalue<'tcx>, Option<MovePathIndex>)>
|
||||||
{
|
{
|
||||||
|
@ -619,7 +619,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
fn open_drop_for_variant<'a>(&mut self,
|
fn open_drop_for_variant<'a>(&mut self,
|
||||||
c: &DropCtxt<'a, 'tcx>,
|
c: &DropCtxt<'a, 'tcx>,
|
||||||
drop_block: &mut Option<BasicBlock>,
|
drop_block: &mut Option<BasicBlock>,
|
||||||
adt: ty::AdtDef<'tcx>,
|
adt: &'tcx ty::AdtDef,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
variant_index: usize)
|
variant_index: usize)
|
||||||
-> BasicBlock
|
-> BasicBlock
|
||||||
|
@ -652,7 +652,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_drop_for_adt<'a>(&mut self, c: &DropCtxt<'a, 'tcx>,
|
fn open_drop_for_adt<'a>(&mut self, c: &DropCtxt<'a, 'tcx>,
|
||||||
adt: ty::AdtDef<'tcx>, substs: &'tcx Substs<'tcx>)
|
adt: &'tcx ty::AdtDef, substs: &'tcx Substs<'tcx>)
|
||||||
-> BasicBlock {
|
-> BasicBlock {
|
||||||
debug!("open_drop_for_adt({:?}, {:?}, {:?})", c, adt, substs);
|
debug!("open_drop_for_adt({:?}, {:?}, {:?})", c, adt, substs);
|
||||||
|
|
||||||
|
|
|
@ -223,10 +223,8 @@ pub enum Constructor {
|
||||||
Slice(usize),
|
Slice(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Constructor {
|
impl<'tcx> Constructor {
|
||||||
fn variant_for_adt<'tcx, 'container, 'a>(&self,
|
fn variant_for_adt(&self, adt: &'tcx ty::AdtDef) -> &'tcx ty::VariantDef {
|
||||||
adt: &'a ty::AdtDefData<'tcx, 'container>)
|
|
||||||
-> &'a ty::VariantDefData<'tcx, 'container> {
|
|
||||||
match self {
|
match self {
|
||||||
&Variant(vid) => adt.variant_with_id(vid),
|
&Variant(vid) => adt.variant_with_id(vid),
|
||||||
&Single => {
|
&Single => {
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub enum PatternKind<'tcx> {
|
||||||
|
|
||||||
/// Foo(...) or Foo{...} or Foo, where `Foo` is a variant name from an adt with >1 variants
|
/// Foo(...) or Foo{...} or Foo, where `Foo` is a variant name from an adt with >1 variants
|
||||||
Variant {
|
Variant {
|
||||||
adt_def: AdtDef<'tcx>,
|
adt_def: &'tcx AdtDef,
|
||||||
variant_index: usize,
|
variant_index: usize,
|
||||||
subpatterns: Vec<FieldPattern<'tcx>>,
|
subpatterns: Vec<FieldPattern<'tcx>>,
|
||||||
},
|
},
|
||||||
|
@ -487,32 +487,22 @@ impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! CopyImpls {
|
macro_rules! CloneImpls {
|
||||||
($($ty:ty),+) => {
|
(<$lt_tcx:tt> $($ty:ty),+) => {
|
||||||
$(
|
$(
|
||||||
impl<'tcx> PatternFoldable<'tcx> for $ty {
|
impl<$lt_tcx> PatternFoldable<$lt_tcx> for $ty {
|
||||||
fn super_fold_with<F: PatternFolder<'tcx>>(&self, _: &mut F) -> Self {
|
fn super_fold_with<F: PatternFolder<$lt_tcx>>(&self, _: &mut F) -> Self {
|
||||||
self.clone()
|
Clone::clone(self)
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! TcxCopyImpls {
|
|
||||||
($($ty:ident),+) => {
|
|
||||||
$(
|
|
||||||
impl<'tcx> PatternFoldable<'tcx> for $ty<'tcx> {
|
|
||||||
fn super_fold_with<F: PatternFolder<'tcx>>(&self, _: &mut F) -> Self {
|
|
||||||
*self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyImpls!{ Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal }
|
CloneImpls!{ <'tcx>
|
||||||
TcxCopyImpls!{ Ty, BindingMode, AdtDef }
|
Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal,
|
||||||
|
Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> {
|
impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> {
|
||||||
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||||
|
|
|
@ -396,7 +396,7 @@ enum FfiResult {
|
||||||
/// expanded to cover NonZero raw pointers and newtypes.
|
/// expanded to cover NonZero raw pointers and newtypes.
|
||||||
/// FIXME: This duplicates code in trans.
|
/// FIXME: This duplicates code in trans.
|
||||||
fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
def: ty::AdtDef<'tcx>,
|
def: &'tcx ty::AdtDef,
|
||||||
substs: &Substs<'tcx>)
|
substs: &Substs<'tcx>)
|
||||||
-> bool {
|
-> bool {
|
||||||
if def.variants.len() == 2 {
|
if def.variants.len() == 2 {
|
||||||
|
|
|
@ -115,13 +115,13 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
||||||
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index)
|
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.dep_graph.read(DepNode::MetaData(def));
|
||||||
self.get_crate_data(def.krate).get_trait_def(def.index, tcx)
|
self.get_crate_data(def.krate).get_trait_def(def.index, tcx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
|
fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef
|
||||||
{
|
{
|
||||||
self.dep_graph.read(DepNode::MetaData(def));
|
self.dep_graph.read(DepNode::MetaData(def));
|
||||||
self.get_crate_data(def.krate).get_adt_def(def.index, tcx)
|
self.get_crate_data(def.krate).get_adt_def(def.index, tcx)
|
||||||
|
|
|
@ -422,8 +422,8 @@ impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::BareFnTy<'tcx>> for DecodeContext<'a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> SpecializedDecoder<ty::AdtDef<'tcx>> for DecodeContext<'a, 'tcx> {
|
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::AdtDef> for DecodeContext<'a, 'tcx> {
|
||||||
fn specialized_decode(&mut self) -> Result<ty::AdtDef<'tcx>, Self::Error> {
|
fn specialized_decode(&mut self) -> Result<&'tcx ty::AdtDef, Self::Error> {
|
||||||
let def_id = DefId::decode(self)?;
|
let def_id = DefId::decode(self)?;
|
||||||
Ok(self.tcx().lookup_adt_def(def_id))
|
Ok(self.tcx().lookup_adt_def(def_id))
|
||||||
}
|
}
|
||||||
|
@ -557,23 +557,22 @@ impl<'a, 'tcx> CrateMetadata {
|
||||||
pub fn get_trait_def(&self,
|
pub fn get_trait_def(&self,
|
||||||
item_id: DefIndex,
|
item_id: DefIndex,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||||
-> ty::TraitDef<'tcx> {
|
-> ty::TraitDef {
|
||||||
let data = match self.entry(item_id).kind {
|
let data = match self.entry(item_id).kind {
|
||||||
EntryKind::Trait(data) => data.decode(self),
|
EntryKind::Trait(data) => data.decode(self),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
ty::TraitDef::new(data.unsafety,
|
ty::TraitDef::new(self.local_def_id(item_id),
|
||||||
|
data.unsafety,
|
||||||
data.paren_sugar,
|
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))
|
self.def_path(item_id).unwrap().deterministic_hash(tcx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_variant(&self,
|
fn get_variant(&self,
|
||||||
item: &Entry<'tcx>,
|
item: &Entry<'tcx>,
|
||||||
index: DefIndex)
|
index: DefIndex)
|
||||||
-> (ty::VariantDefData<'tcx, 'tcx>, Option<DefIndex>) {
|
-> (ty::VariantDef, Option<DefIndex>) {
|
||||||
let data = match item.kind {
|
let data = match item.kind {
|
||||||
EntryKind::Variant(data) |
|
EntryKind::Variant(data) |
|
||||||
EntryKind::Struct(data) |
|
EntryKind::Struct(data) |
|
||||||
|
@ -581,28 +580,26 @@ impl<'a, 'tcx> CrateMetadata {
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let fields = item.children
|
(ty::VariantDef {
|
||||||
.decode(self)
|
did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
|
||||||
.map(|index| {
|
name: self.item_name(item),
|
||||||
|
fields: item.children.decode(self).map(|index| {
|
||||||
let f = self.entry(index);
|
let f = self.entry(index);
|
||||||
ty::FieldDefData::new(self.local_def_id(index), self.item_name(&f), f.visibility)
|
ty::FieldDef {
|
||||||
})
|
did: self.local_def_id(index),
|
||||||
.collect();
|
name: self.item_name(&f),
|
||||||
|
vis: f.visibility
|
||||||
(ty::VariantDefData {
|
}
|
||||||
did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
|
}).collect(),
|
||||||
name: self.item_name(item),
|
disr_val: ConstInt::Infer(data.disr),
|
||||||
fields: fields,
|
ctor_kind: data.ctor_kind,
|
||||||
disr_val: ConstInt::Infer(data.disr),
|
}, data.struct_ctor)
|
||||||
ctor_kind: data.ctor_kind,
|
|
||||||
},
|
|
||||||
data.struct_ctor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_adt_def(&self,
|
pub fn get_adt_def(&self,
|
||||||
item_id: DefIndex,
|
item_id: DefIndex,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||||
-> ty::AdtDefMaster<'tcx> {
|
-> &'tcx ty::AdtDef {
|
||||||
let item = self.entry(item_id);
|
let item = self.entry(item_id);
|
||||||
let did = self.local_def_id(item_id);
|
let did = self.local_def_id(item_id);
|
||||||
let mut ctor_index = None;
|
let mut ctor_index = None;
|
||||||
|
@ -627,26 +624,10 @@ impl<'a, 'tcx> CrateMetadata {
|
||||||
_ => bug!("get_adt_def called on a non-ADT {:?}", did),
|
_ => bug!("get_adt_def called on a non-ADT {:?}", did),
|
||||||
};
|
};
|
||||||
|
|
||||||
let adt = tcx.intern_adt_def(did, kind, variants);
|
let adt = tcx.alloc_adt_def(did, kind, variants);
|
||||||
if let Some(ctor_index) = ctor_index {
|
if let Some(ctor_index) = ctor_index {
|
||||||
// Make adt definition available through constructor id as well.
|
// Make adt definition available through constructor id as well.
|
||||||
tcx.insert_adt_def(self.local_def_id(ctor_index), adt);
|
tcx.adt_defs.borrow_mut().insert(self.local_def_id(ctor_index), adt);
|
||||||
}
|
|
||||||
|
|
||||||
// this needs to be done *after* the variant is interned,
|
|
||||||
// to support recursive structures
|
|
||||||
for variant in &adt.variants {
|
|
||||||
for field in &variant.fields {
|
|
||||||
debug!("evaluating the type of {:?}::{:?}",
|
|
||||||
variant.name,
|
|
||||||
field.name);
|
|
||||||
let ty = self.get_type(field.did.index, tcx);
|
|
||||||
field.fulfill_ty(ty);
|
|
||||||
debug!("evaluating the type of {:?}::{:?}: {:?}",
|
|
||||||
variant.name,
|
|
||||||
field.name,
|
|
||||||
ty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
adt
|
adt
|
||||||
|
|
|
@ -736,7 +736,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
unsafety: trait_def.unsafety,
|
unsafety: trait_def.unsafety,
|
||||||
paren_sugar: trait_def.paren_sugar,
|
paren_sugar: trait_def.paren_sugar,
|
||||||
has_default_impl: tcx.trait_has_default_impl(def_id),
|
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)),
|
super_predicates: self.lazy(&tcx.item_super_predicates(def_id)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,6 @@ pub struct TraitData<'tcx> {
|
||||||
pub unsafety: hir::Unsafety,
|
pub unsafety: hir::Unsafety,
|
||||||
pub paren_sugar: bool,
|
pub paren_sugar: bool,
|
||||||
pub has_default_impl: bool,
|
pub has_default_impl: bool,
|
||||||
pub trait_ref: Lazy<ty::TraitRef<'tcx>>,
|
|
||||||
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
|
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,7 @@ pub struct MatchPair<'pat, 'tcx:'pat> {
|
||||||
enum TestKind<'tcx> {
|
enum TestKind<'tcx> {
|
||||||
// test the branches of enum
|
// test the branches of enum
|
||||||
Switch {
|
Switch {
|
||||||
adt_def: AdtDef<'tcx>,
|
adt_def: &'tcx AdtDef,
|
||||||
variants: BitVector,
|
variants: BitVector,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -615,7 +615,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
fn candidate_after_variant_switch<'pat>(&mut self,
|
fn candidate_after_variant_switch<'pat>(&mut self,
|
||||||
match_pair_index: usize,
|
match_pair_index: usize,
|
||||||
adt_def: ty::AdtDef<'tcx>,
|
adt_def: &'tcx ty::AdtDef,
|
||||||
variant_index: usize,
|
variant_index: usize,
|
||||||
subpatterns: &'pat [FieldPattern<'tcx>],
|
subpatterns: &'pat [FieldPattern<'tcx>],
|
||||||
candidate: &Candidate<'pat, 'tcx>)
|
candidate: &Candidate<'pat, 'tcx>)
|
||||||
|
|
|
@ -1003,7 +1003,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef.
|
/// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef.
|
||||||
fn field_refs<'tcx>(variant: VariantDef<'tcx>,
|
fn field_refs<'tcx>(variant: &'tcx VariantDef,
|
||||||
fields: &'tcx [hir::Field])
|
fields: &'tcx [hir::Field])
|
||||||
-> Vec<FieldExprRef<'tcx>>
|
-> Vec<FieldExprRef<'tcx>>
|
||||||
{
|
{
|
||||||
|
|
|
@ -155,11 +155,11 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
|
||||||
bug!("found no method `{}` in `{:?}`", method_name, trait_def_id);
|
bug!("found no method `{}` in `{:?}`", method_name, trait_def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_variants(&mut self, adt_def: ty::AdtDef) -> usize {
|
pub fn num_variants(&mut self, adt_def: &ty::AdtDef) -> usize {
|
||||||
adt_def.variants.len()
|
adt_def.variants.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_fields(&mut self, adt_def: ty::AdtDef, variant_index: usize) -> Vec<Field> {
|
pub fn all_fields(&mut self, adt_def: &ty::AdtDef, variant_index: usize) -> Vec<Field> {
|
||||||
(0..adt_def.variants[variant_index].fields.len())
|
(0..adt_def.variants[variant_index].fields.len())
|
||||||
.map(Field::new)
|
.map(Field::new)
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -221,7 +221,7 @@ pub enum ExprKind<'tcx> {
|
||||||
fields: Vec<ExprRef<'tcx>>,
|
fields: Vec<ExprRef<'tcx>>,
|
||||||
},
|
},
|
||||||
Adt {
|
Adt {
|
||||||
adt_def: AdtDef<'tcx>,
|
adt_def: &'tcx AdtDef,
|
||||||
variant_index: usize,
|
variant_index: usize,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
fields: Vec<FieldExprRef<'tcx>>,
|
fields: Vec<FieldExprRef<'tcx>>,
|
||||||
|
|
|
@ -405,7 +405,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that a field is in scope.
|
// Checks that a field is in scope.
|
||||||
fn check_field(&mut self, span: Span, def: ty::AdtDef<'tcx>, field: ty::FieldDef<'tcx>) {
|
fn check_field(&mut self, span: Span, def: &'tcx ty::AdtDef, field: &'tcx ty::FieldDef) {
|
||||||
if !def.is_enum() && !field.vis.is_accessible_from(self.curitem, &self.tcx.map) {
|
if !def.is_enum() && !field.vis.is_accessible_from(self.curitem, &self.tcx.map) {
|
||||||
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
|
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
|
||||||
field.name, def.variant_descr(), self.tcx.item_path_str(def.did))
|
field.name, def.variant_descr(), self.tcx.item_path_str(def.did))
|
||||||
|
|
|
@ -941,7 +941,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
ex: &ast::Expr,
|
ex: &ast::Expr,
|
||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
fields: &Vec<ast::Field>,
|
fields: &Vec<ast::Field>,
|
||||||
variant: ty::VariantDef,
|
variant: &ty::VariantDef,
|
||||||
base: &Option<P<ast::Expr>>) {
|
base: &Option<P<ast::Expr>>) {
|
||||||
self.write_sub_paths_truncated(path, false);
|
self.write_sub_paths_truncated(path, false);
|
||||||
|
|
||||||
|
|
|
@ -621,7 +621,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
|
|
||||||
pub fn get_field_ref_data(&self,
|
pub fn get_field_ref_data(&self,
|
||||||
field_ref: &ast::Field,
|
field_ref: &ast::Field,
|
||||||
variant: ty::VariantDef,
|
variant: &ty::VariantDef,
|
||||||
parent: NodeId)
|
parent: NodeId)
|
||||||
-> Option<VariableRefData> {
|
-> Option<VariableRefData> {
|
||||||
let f = variant.field_named(field_ref.ident.node.name);
|
let f = variant.field_named(field_ref.ident.node.name);
|
||||||
|
|
|
@ -803,9 +803,10 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
ty::TyAdt(adt_def, substs) => {
|
ty::TyAdt(adt_def, substs) => {
|
||||||
for field in adt_def.all_fields() {
|
for field in adt_def.all_fields() {
|
||||||
|
let field_type = scx.tcx().item_type(field.did);
|
||||||
let field_type = monomorphize::apply_param_substs(scx,
|
let field_type = monomorphize::apply_param_substs(scx,
|
||||||
substs,
|
substs,
|
||||||
&field.unsubst_ty());
|
&field_type);
|
||||||
let field_type = glue::get_drop_glue_type(scx.tcx(), field_type);
|
let field_type = glue::get_drop_glue_type(scx.tcx(), field_type);
|
||||||
|
|
||||||
if glue::type_needs_drop(scx.tcx(), field_type) {
|
if glue::type_needs_drop(scx.tcx(), field_type) {
|
||||||
|
|
|
@ -882,7 +882,7 @@ impl<'tcx> MemberDescriptionFactory<'tcx> {
|
||||||
|
|
||||||
// Creates MemberDescriptions for the fields of a struct
|
// Creates MemberDescriptions for the fields of a struct
|
||||||
struct StructMemberDescriptionFactory<'tcx> {
|
struct StructMemberDescriptionFactory<'tcx> {
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
is_simd: bool,
|
is_simd: bool,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -1024,7 +1024,7 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
//=-----------------------------------------------------------------------------
|
//=-----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct UnionMemberDescriptionFactory<'tcx> {
|
struct UnionMemberDescriptionFactory<'tcx> {
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
@ -1338,7 +1338,7 @@ enum EnumDiscriminantInfo {
|
||||||
fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
enum_type: Ty<'tcx>,
|
enum_type: Ty<'tcx>,
|
||||||
struct_def: &layout::Struct,
|
struct_def: &layout::Struct,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
discriminant_info: EnumDiscriminantInfo,
|
discriminant_info: EnumDiscriminantInfo,
|
||||||
containing_scope: DIScope,
|
containing_scope: DIScope,
|
||||||
span: Span)
|
span: Span)
|
||||||
|
@ -1357,7 +1357,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
ref l @ _ => bug!("This should be unreachable. Type is {:#?} layout is {:#?}", enum_type, l)
|
ref l @ _ => bug!("This should be unreachable. Type is {:#?} layout is {:#?}", enum_type, l)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut field_tys = variant.fields.iter().map(|f: ty::FieldDef<'tcx>| {
|
let mut field_tys = variant.fields.iter().map(|f| {
|
||||||
monomorphize::field_ty(cx.tcx(), &substs, f)
|
monomorphize::field_ty(cx.tcx(), &substs, f)
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
|
@ -504,7 +504,7 @@ fn drop_structural_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
||||||
fn iter_variant<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
fn iter_variant<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
||||||
t: Ty<'tcx>,
|
t: Ty<'tcx>,
|
||||||
av: adt::MaybeSizedValue,
|
av: adt::MaybeSizedValue,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
substs: &Substs<'tcx>)
|
substs: &Substs<'tcx>)
|
||||||
-> Block<'blk, 'tcx> {
|
-> Block<'blk, 'tcx> {
|
||||||
let _icx = push_ctxt("iter_variant");
|
let _icx = push_ctxt("iter_variant");
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub fn apply_param_substs<'a, 'tcx, T>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||||
/// Returns the normalized type of a struct field
|
/// Returns the normalized type of a struct field
|
||||||
pub fn field_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn field_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
param_substs: &Substs<'tcx>,
|
param_substs: &Substs<'tcx>,
|
||||||
f: ty::FieldDef<'tcx>)
|
f: &'tcx ty::FieldDef)
|
||||||
-> Ty<'tcx>
|
-> Ty<'tcx>
|
||||||
{
|
{
|
||||||
tcx.normalize_associated_type(&f.ty(tcx, param_substs))
|
tcx.normalize_associated_type(&f.ty(tcx, param_substs))
|
||||||
|
|
|
@ -93,7 +93,7 @@ pub trait AstConv<'gcx, 'tcx> {
|
||||||
/// Returns the `TraitDef` for a given trait. This allows you to
|
/// Returns the `TraitDef` for a given trait. This allows you to
|
||||||
/// figure out the set of type parameters defined on the trait.
|
/// figure out the set of type parameters defined on the trait.
|
||||||
fn get_trait_def(&self, span: Span, id: DefId)
|
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
|
/// Ensure that the super-predicates for the trait with the given
|
||||||
/// id are available and also for the transitive set of
|
/// id are available and also for the transitive set of
|
||||||
|
|
|
@ -626,7 +626,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
adt_ty: Ty<'tcx>,
|
adt_ty: Ty<'tcx>,
|
||||||
pat_id: ast::NodeId,
|
pat_id: ast::NodeId,
|
||||||
span: Span,
|
span: Span,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
fields: &'gcx [Spanned<hir::FieldPat>],
|
fields: &'gcx [Spanned<hir::FieldPat>],
|
||||||
etc: bool) {
|
etc: bool) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
|
|
@ -589,7 +589,7 @@ fn has_dtor_of_interest<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
//
|
//
|
||||||
// then revises input: `Foo<'r,i64,&'r i64>` to: `Foo<'static,i64,()>`
|
// then revises input: `Foo<'r,i64,&'r i64>` to: `Foo<'static,i64,()>`
|
||||||
fn revise_self_ty<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
fn revise_self_ty<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
adt_def: ty::AdtDef<'tcx>,
|
adt_def: &'tcx ty::AdtDef,
|
||||||
impl_def_id: DefId,
|
impl_def_id: DefId,
|
||||||
substs: &Substs<'tcx>)
|
substs: &Substs<'tcx>)
|
||||||
-> Ty<'tcx> {
|
-> Ty<'tcx> {
|
||||||
|
|
|
@ -192,13 +192,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
m_name,
|
m_name,
|
||||||
trait_def_id);
|
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>`
|
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
||||||
let substs = Substs::for_item(self.tcx,
|
let substs = Substs::for_item(self.tcx,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
|
|
|
@ -1041,7 +1041,7 @@ fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_specialization_validity<'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_id: DefId,
|
||||||
impl_item: &hir::ImplItem)
|
impl_item: &hir::ImplItem)
|
||||||
{
|
{
|
||||||
|
@ -1401,7 +1401,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_trait_def(&self, _: Span, id: DefId)
|
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))
|
Ok(self.tcx().lookup_trait_def(id))
|
||||||
}
|
}
|
||||||
|
@ -1987,7 +1987,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
// Indifferent to privacy flags
|
// Indifferent to privacy flags
|
||||||
pub fn field_ty(&self,
|
pub fn field_ty(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
field: ty::FieldDef<'tcx>,
|
field: &'tcx ty::FieldDef,
|
||||||
substs: &Substs<'tcx>)
|
substs: &Substs<'tcx>)
|
||||||
-> Ty<'tcx>
|
-> Ty<'tcx>
|
||||||
{
|
{
|
||||||
|
@ -3073,7 +3073,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an hint about the closest match in field names
|
// Return an hint about the closest match in field names
|
||||||
fn suggest_field_name(variant: ty::VariantDef<'tcx>,
|
fn suggest_field_name(variant: &'tcx ty::VariantDef,
|
||||||
field: &Spanned<ast::Name>,
|
field: &Spanned<ast::Name>,
|
||||||
skip : Vec<InternedString>)
|
skip : Vec<InternedString>)
|
||||||
-> Option<Symbol> {
|
-> Option<Symbol> {
|
||||||
|
@ -3166,7 +3166,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
fn report_unknown_field(&self,
|
fn report_unknown_field(&self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
field: &hir::Field,
|
field: &hir::Field,
|
||||||
skip_fields: &[hir::Field],
|
skip_fields: &[hir::Field],
|
||||||
kind_name: &str) {
|
kind_name: &str) {
|
||||||
|
@ -3210,7 +3210,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
adt_ty: Ty<'tcx>,
|
adt_ty: Ty<'tcx>,
|
||||||
expr_id: ast::NodeId,
|
expr_id: ast::NodeId,
|
||||||
span: Span,
|
span: Span,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
ast_fields: &'gcx [hir::Field],
|
ast_fields: &'gcx [hir::Field],
|
||||||
check_completeness: bool) {
|
check_completeness: bool) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
@ -3326,7 +3326,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
pub fn check_struct_path(&self,
|
pub fn check_struct_path(&self,
|
||||||
qpath: &hir::QPath,
|
qpath: &hir::QPath,
|
||||||
node_id: ast::NodeId)
|
node_id: ast::NodeId)
|
||||||
-> Option<(ty::VariantDef<'tcx>, Ty<'tcx>)> {
|
-> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
|
||||||
let path_span = match *qpath {
|
let path_span = match *qpath {
|
||||||
hir::QPath::Resolved(_, ref path) => path.span,
|
hir::QPath::Resolved(_, ref path) => path.span,
|
||||||
hir::QPath::TypeRelative(ref qself, _) => qself.span
|
hir::QPath::TypeRelative(ref qself, _) => qself.span
|
||||||
|
|
|
@ -285,12 +285,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let trait_def = self.tcx().lookup_trait_def(trait_def_id);
|
let has_ty_params = self.tcx().item_generics(trait_def_id).types.len() > 1;
|
||||||
|
|
||||||
let has_ty_params =
|
|
||||||
trait_def.generics
|
|
||||||
.types
|
|
||||||
.len() > 1;
|
|
||||||
|
|
||||||
// We use an if-else here, since the generics will also trigger
|
// We use an if-else here, since the generics will also trigger
|
||||||
// an extraneous error message when we find predicates like
|
// an extraneous error message when we find predicates like
|
||||||
|
|
|
@ -395,7 +395,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
|
||||||
.filter_map(|(i, f)| {
|
.filter_map(|(i, f)| {
|
||||||
let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));
|
let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));
|
||||||
|
|
||||||
if f.unsubst_ty().is_phantom_data() {
|
if tcx.item_type(f.did).is_phantom_data() {
|
||||||
// Ignore PhantomData fields
|
// Ignore PhantomData fields
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,20 +329,21 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
|
/// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
|
||||||
fn get_trait_def(&self, trait_id: DefId)
|
fn get_trait_def(&self, def_id: DefId)
|
||||||
-> &'tcx ty::TraitDef<'tcx>
|
-> &'tcx ty::TraitDef
|
||||||
{
|
{
|
||||||
let tcx = self.tcx;
|
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) {
|
let item = match tcx.map.get(trait_id) {
|
||||||
hir_map::NodeItem(item) => item,
|
hir_map::NodeItem(item) => item,
|
||||||
_ => bug!("get_trait_def({:?}): not an item", trait_id)
|
_ => bug!("get_trait_def({:?}): not an item", trait_id)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
generics_of_def_id(self, def_id);
|
||||||
trait_def_of_item(self, &item)
|
trait_def_of_item(self, &item)
|
||||||
} else {
|
} 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)
|
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), || {
|
self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
|
||||||
Ok(self.ccx.get_trait_def(id))
|
Ok(self.ccx.get_trait_def(id))
|
||||||
|
@ -616,10 +617,10 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
struct_generics: &'tcx ty::Generics<'tcx>,
|
struct_generics: &'tcx ty::Generics<'tcx>,
|
||||||
struct_predicates: &ty::GenericPredicates<'tcx>,
|
struct_predicates: &ty::GenericPredicates<'tcx>,
|
||||||
field: &hir::StructField,
|
field: &hir::StructField,
|
||||||
ty_f: ty::FieldDefMaster<'tcx>)
|
ty_f: &'tcx ty::FieldDef)
|
||||||
{
|
{
|
||||||
let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty);
|
let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty);
|
||||||
ty_f.fulfill_ty(tt);
|
ccx.tcx.item_types.borrow_mut().insert(ty_f.did, tt);
|
||||||
|
|
||||||
let def_id = ccx.tcx.map.local_def_id(field.id);
|
let def_id = ccx.tcx.map.local_def_id(field.id);
|
||||||
ccx.tcx.item_types.borrow_mut().insert(def_id, tt);
|
ccx.tcx.item_types.borrow_mut().insert(def_id, tt);
|
||||||
|
@ -716,6 +717,7 @@ fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
|
||||||
fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
debug!("convert: item {} with id {}", it.name, it.id);
|
debug!("convert: item {} with id {}", it.name, it.id);
|
||||||
|
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||||
match it.node {
|
match it.node {
|
||||||
// These don't define types.
|
// These don't define types.
|
||||||
hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
|
hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
|
||||||
|
@ -726,12 +728,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemEnum(ref enum_definition, _) => {
|
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 ty = type_of_def_id(ccx, def_id);
|
||||||
let generics = generics_of_def_id(ccx, def_id);
|
let generics = generics_of_def_id(ccx, def_id);
|
||||||
let predicates = predicates_of_item(ccx, it);
|
let predicates = predicates_of_item(ccx, it);
|
||||||
convert_enum_variant_types(ccx,
|
convert_enum_variant_types(ccx,
|
||||||
tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
|
tcx.lookup_adt_def(ccx.tcx.map.local_def_id(it.id)),
|
||||||
ty,
|
ty,
|
||||||
generics,
|
generics,
|
||||||
predicates,
|
predicates,
|
||||||
|
@ -756,7 +757,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||||
_) => {
|
_) => {
|
||||||
// Create generics from the generics specified in the impl head.
|
// Create generics from the generics specified in the impl head.
|
||||||
debug!("convert: ast_generics={:?}", generics);
|
debug!("convert: ast_generics={:?}", generics);
|
||||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
|
||||||
generics_of_def_id(ccx, def_id);
|
generics_of_def_id(ccx, def_id);
|
||||||
let mut ty_predicates =
|
let mut ty_predicates =
|
||||||
ty_generic_predicates(ccx, generics, None, vec![], false);
|
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());
|
tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
|
||||||
},
|
},
|
||||||
hir::ItemTrait(.., ref trait_items) => {
|
hir::ItemTrait(.., ref trait_items) => {
|
||||||
let trait_def = trait_def_of_item(ccx, it);
|
generics_of_def_id(ccx, def_id);
|
||||||
let def_id = trait_def.trait_ref.def_id;
|
trait_def_of_item(ccx, it);
|
||||||
let _: Result<(), ErrorReported> = // any error is already reported, can ignore
|
let _: Result<(), ErrorReported> = // any error is already reported, can ignore
|
||||||
ccx.ensure_super_predicates(it.span, def_id);
|
ccx.ensure_super_predicates(it.span, def_id);
|
||||||
convert_trait_predicates(ccx, it);
|
convert_trait_predicates(ccx, it);
|
||||||
|
@ -838,12 +838,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||||
},
|
},
|
||||||
hir::ItemStruct(ref struct_def, _) |
|
hir::ItemStruct(ref struct_def, _) |
|
||||||
hir::ItemUnion(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 ty = type_of_def_id(ccx, def_id);
|
||||||
let generics = generics_of_def_id(ccx, def_id);
|
let generics = generics_of_def_id(ccx, def_id);
|
||||||
let predicates = predicates_of_item(ccx, it);
|
let predicates = predicates_of_item(ccx, it);
|
||||||
|
|
||||||
let variant = tcx.lookup_adt_def_master(def_id).struct_variant();
|
let variant = tcx.lookup_adt_def(def_id).struct_variant();
|
||||||
|
|
||||||
for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
|
for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) {
|
||||||
convert_field(ccx, generics, &predicates, f, ty_f)
|
convert_field(ccx, generics, &predicates, f, ty_f)
|
||||||
|
@ -855,13 +854,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||||
},
|
},
|
||||||
hir::ItemTy(_, ref generics) => {
|
hir::ItemTy(_, ref generics) => {
|
||||||
ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
|
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);
|
type_of_def_id(ccx, def_id);
|
||||||
generics_of_def_id(ccx, def_id);
|
generics_of_def_id(ccx, def_id);
|
||||||
predicates_of_item(ccx, it);
|
predicates_of_item(ccx, it);
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
|
||||||
type_of_def_id(ccx, def_id);
|
type_of_def_id(ccx, def_id);
|
||||||
generics_of_def_id(ccx, def_id);
|
generics_of_def_id(ccx, def_id);
|
||||||
predicates_of_item(ccx, it);
|
predicates_of_item(ccx, it);
|
||||||
|
@ -914,7 +911,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) {
|
||||||
|
|
||||||
fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
ctor_id: ast::NodeId,
|
ctor_id: ast::NodeId,
|
||||||
variant: ty::VariantDef<'tcx>,
|
variant: &'tcx ty::VariantDef,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
predicates: ty::GenericPredicates<'tcx>) {
|
predicates: ty::GenericPredicates<'tcx>) {
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
|
@ -926,7 +923,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
let inputs: Vec<_> =
|
let inputs: Vec<_> =
|
||||||
variant.fields
|
variant.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| field.unsubst_ty())
|
.map(|field| tcx.item_type(field.did))
|
||||||
.collect();
|
.collect();
|
||||||
let substs = mk_item_substs(&ccx.icx(&predicates),
|
let substs = mk_item_substs(&ccx.icx(&predicates),
|
||||||
ccx.tcx.map.span(ctor_id), def_id);
|
ccx.tcx.map.span(ctor_id), def_id);
|
||||||
|
@ -946,7 +943,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
def: ty::AdtDefMaster<'tcx>,
|
def: &'tcx ty::AdtDef,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
generics: &'tcx ty::Generics<'tcx>,
|
generics: &'tcx ty::Generics<'tcx>,
|
||||||
predicates: ty::GenericPredicates<'tcx>,
|
predicates: ty::GenericPredicates<'tcx>,
|
||||||
|
@ -974,7 +971,7 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
name: ast::Name,
|
name: ast::Name,
|
||||||
disr_val: ty::Disr,
|
disr_val: ty::Disr,
|
||||||
def: &hir::VariantData)
|
def: &hir::VariantData)
|
||||||
-> ty::VariantDefData<'tcx, 'tcx> {
|
-> ty::VariantDef {
|
||||||
let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
|
let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
|
||||||
let node_id = ccx.tcx.map.as_local_node_id(did).unwrap();
|
let node_id = ccx.tcx.map.as_local_node_id(did).unwrap();
|
||||||
let fields = def.fields().iter().map(|f| {
|
let fields = def.fields().iter().map(|f| {
|
||||||
|
@ -991,10 +988,13 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
seen_fields.insert(f.name, f.span);
|
seen_fields.insert(f.name, f.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FieldDefData::new(fid, f.name,
|
ty::FieldDef {
|
||||||
ty::Visibility::from_hir(&f.vis, node_id, ccx.tcx))
|
did: fid,
|
||||||
|
name: f.name,
|
||||||
|
vis: ty::Visibility::from_hir(&f.vis, node_id, ccx.tcx)
|
||||||
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
ty::VariantDefData {
|
ty::VariantDef {
|
||||||
did: did,
|
did: did,
|
||||||
name: name,
|
name: name,
|
||||||
disr_val: disr_val,
|
disr_val: disr_val,
|
||||||
|
@ -1006,29 +1006,34 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
it: &hir::Item,
|
it: &hir::Item,
|
||||||
def: &hir::VariantData)
|
def: &hir::VariantData)
|
||||||
-> ty::AdtDefMaster<'tcx>
|
-> &'tcx ty::AdtDef
|
||||||
{
|
{
|
||||||
let did = ccx.tcx.map.local_def_id(it.id);
|
let did = ccx.tcx.map.local_def_id(it.id);
|
||||||
// Use separate constructor id for unit/tuple structs and reuse did for braced structs.
|
// Use separate constructor id for unit/tuple structs and reuse did for braced structs.
|
||||||
let ctor_id = if !def.is_struct() { Some(ccx.tcx.map.local_def_id(def.id())) } else { None };
|
let ctor_id = if !def.is_struct() { Some(ccx.tcx.map.local_def_id(def.id())) } else { None };
|
||||||
let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name,
|
let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name,
|
||||||
ConstInt::Infer(0), def)];
|
ConstInt::Infer(0), def)];
|
||||||
let adt = ccx.tcx.intern_adt_def(did, AdtKind::Struct, variants);
|
let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Struct, variants);
|
||||||
if let Some(ctor_id) = ctor_id {
|
if let Some(ctor_id) = ctor_id {
|
||||||
// Make adt definition available through constructor id as well.
|
// Make adt definition available through constructor id as well.
|
||||||
ccx.tcx.insert_adt_def(ctor_id, adt);
|
ccx.tcx.adt_defs.borrow_mut().insert(ctor_id, adt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccx.tcx.adt_defs.borrow_mut().insert(did, adt);
|
||||||
adt
|
adt
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
it: &hir::Item,
|
it: &hir::Item,
|
||||||
def: &hir::VariantData)
|
def: &hir::VariantData)
|
||||||
-> ty::AdtDefMaster<'tcx>
|
-> &'tcx ty::AdtDef
|
||||||
{
|
{
|
||||||
let did = ccx.tcx.map.local_def_id(it.id);
|
let did = ccx.tcx.map.local_def_id(it.id);
|
||||||
let variants = vec![convert_struct_variant(ccx, did, it.name, ConstInt::Infer(0), def)];
|
let variants = vec![convert_struct_variant(ccx, did, it.name, ConstInt::Infer(0), def)];
|
||||||
ccx.tcx.intern_adt_def(did, AdtKind::Union, variants)
|
|
||||||
|
let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, variants);
|
||||||
|
ccx.tcx.adt_defs.borrow_mut().insert(did, adt);
|
||||||
|
adt
|
||||||
}
|
}
|
||||||
|
|
||||||
fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr)
|
fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr)
|
||||||
|
@ -1082,7 +1087,7 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
it: &hir::Item,
|
it: &hir::Item,
|
||||||
def: &hir::EnumDef)
|
def: &hir::EnumDef)
|
||||||
-> ty::AdtDefMaster<'tcx>
|
-> &'tcx ty::AdtDef
|
||||||
{
|
{
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
let did = tcx.map.local_def_id(it.id);
|
let did = tcx.map.local_def_id(it.id);
|
||||||
|
@ -1110,7 +1115,10 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
let did = tcx.map.local_def_id(v.node.data.id());
|
let did = tcx.map.local_def_id(v.node.data.id());
|
||||||
convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
|
convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
|
||||||
}).collect();
|
}).collect();
|
||||||
tcx.intern_adt_def(tcx.map.local_def_id(it.id), AdtKind::Enum, variants)
|
|
||||||
|
let adt = tcx.alloc_adt_def(did, AdtKind::Enum, variants);
|
||||||
|
tcx.adt_defs.borrow_mut().insert(did, adt);
|
||||||
|
adt
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that the super-predicates of the trait with def-id
|
/// Ensures that the super-predicates of the trait with def-id
|
||||||
|
@ -1155,10 +1163,15 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
|
||||||
// In-scope when converting the superbounds for `Trait` are
|
// In-scope when converting the superbounds for `Trait` are
|
||||||
// that `Self:Trait` as well as any bounds that appear on the
|
// that `Self:Trait` as well as any bounds that appear on the
|
||||||
// generic types:
|
// 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 {
|
let self_predicate = ty::GenericPredicates {
|
||||||
parent: None,
|
parent: None,
|
||||||
predicates: vec![trait_def.trait_ref.to_predicate()]
|
predicates: vec![trait_ref.to_predicate()]
|
||||||
};
|
};
|
||||||
let scope = &(generics, &self_predicate);
|
let scope = &(generics, &self_predicate);
|
||||||
|
|
||||||
|
@ -1203,54 +1216,41 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
|
||||||
def_ids
|
def_ids
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'tcx ty::TraitDef {
|
||||||
it: &hir::Item)
|
|
||||||
-> &'tcx ty::TraitDef<'tcx>
|
|
||||||
{
|
|
||||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
|
|
||||||
if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
|
tcx.trait_defs.memoize(def_id, || {
|
||||||
return def.clone();
|
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 {
|
let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
|
||||||
hir::ItemTrait(unsafety, ref generics, _, _) => {
|
if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
|
||||||
(unsafety, generics)
|
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");
|
let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
|
||||||
if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
|
tcx.alloc_trait_def(ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash))
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
|
fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
let trait_def = trait_def_of_item(ccx, it);
|
|
||||||
|
|
||||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
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 {
|
let (generics, items) = match it.node {
|
||||||
hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
|
hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
|
||||||
ref s => {
|
ref s => {
|
||||||
|
@ -1272,7 +1272,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
|
// Add in a predicate that `Self:Trait` (where `Trait` is the
|
||||||
// current trait). This is needed for builtin bounds.
|
// 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);
|
base_predicates.push(self_predicate);
|
||||||
|
|
||||||
// add in the explicit where-clauses
|
// add in the explicit where-clauses
|
||||||
|
@ -1282,7 +1286,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
|
||||||
let assoc_predicates = predicates_for_associated_types(ccx,
|
let assoc_predicates = predicates_for_associated_types(ccx,
|
||||||
generics,
|
generics,
|
||||||
&trait_predicates,
|
&trait_predicates,
|
||||||
trait_def.trait_ref,
|
trait_ref,
|
||||||
items);
|
items);
|
||||||
trait_predicates.predicates.extend(assoc_predicates);
|
trait_predicates.predicates.extend(assoc_predicates);
|
||||||
|
|
||||||
|
@ -1581,7 +1585,10 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
|
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
|
||||||
ccx.tcx.mk_closure(def_id, Substs::for_item(
|
ccx.tcx.mk_closure(def_id, Substs::for_item(
|
||||||
ccx.tcx, def_id,
|
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)
|
|def, _| ccx.tcx.mk_param_from_def(def)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -2096,7 +2103,5 @@ pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||||
bug!("ErrorReported returned, but no errors reports?")
|
bug!("ErrorReported returned, but no errors reports?")
|
||||||
}
|
}
|
||||||
|
|
||||||
Substs::for_item(tcx, def_id,
|
Substs::identity_for_item(tcx, def_id)
|
||||||
|def, _| tcx.mk_region(def.to_early_bound_region()),
|
|
||||||
|def, _| tcx.mk_param_from_def(def))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,14 +92,18 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
|
||||||
|
|
||||||
for field in tcx.lookup_adt_def(did).all_fields() {
|
for field in tcx.lookup_adt_def(did).all_fields() {
|
||||||
self.add_constraints_from_ty(generics,
|
self.add_constraints_from_ty(generics,
|
||||||
field.unsubst_ty(),
|
tcx.item_type(field.did),
|
||||||
self.covariant);
|
self.covariant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemTrait(..) => {
|
hir::ItemTrait(..) => {
|
||||||
let trait_def = tcx.lookup_trait_def(did);
|
let generics = tcx.item_generics(did);
|
||||||
self.add_constraints_from_trait_ref(&trait_def.generics,
|
let trait_ref = ty::TraitRef {
|
||||||
trait_def.trait_ref,
|
def_id: did,
|
||||||
|
substs: Substs::identity_for_item(tcx, did)
|
||||||
|
};
|
||||||
|
self.add_constraints_from_trait_ref(generics,
|
||||||
|
trait_ref,
|
||||||
self.invariant);
|
self.invariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +283,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||||
trait_ref,
|
trait_ref,
|
||||||
variance);
|
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
|
// This edge is actually implied by the call to
|
||||||
// `lookup_trait_def`, but I'm trying to be future-proof. See
|
// `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,
|
self.add_constraints_from_substs(generics,
|
||||||
trait_ref.def_id,
|
trait_ref.def_id,
|
||||||
&trait_def.generics.types,
|
&trait_generics.types,
|
||||||
&trait_def.generics.regions,
|
&trait_generics.regions,
|
||||||
trait_ref.substs,
|
trait_ref.substs,
|
||||||
variance);
|
variance);
|
||||||
}
|
}
|
||||||
|
@ -356,7 +360,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||||
|
|
||||||
ty::TyProjection(ref data) => {
|
ty::TyProjection(ref data) => {
|
||||||
let trait_ref = &data.trait_ref;
|
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
|
// This edge is actually implied by the call to
|
||||||
// `lookup_trait_def`, but I'm trying to be future-proof. See
|
// `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,
|
self.add_constraints_from_substs(generics,
|
||||||
trait_ref.def_id,
|
trait_ref.def_id,
|
||||||
&trait_def.generics.types,
|
&trait_generics.types,
|
||||||
&trait_def.generics.regions,
|
&trait_generics.regions,
|
||||||
trait_ref.substs,
|
trait_ref.substs,
|
||||||
variance);
|
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 {
|
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 trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect();
|
||||||
let predicates = cx.tcx.item_predicates(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);
|
||||||
let generics = filter_non_trait_generics(did, generics);
|
let generics = filter_non_trait_generics(did, generics);
|
||||||
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
|
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
|
||||||
clean::Trait {
|
clean::Trait {
|
||||||
unsafety: def.unsafety,
|
unsafety: cx.tcx.lookup_trait_def(did).unsafety,
|
||||||
generics: generics,
|
generics: generics,
|
||||||
items: trait_items,
|
items: trait_items,
|
||||||
bounds: supertrait_bounds,
|
bounds: supertrait_bounds,
|
||||||
|
|
|
@ -1395,9 +1395,8 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
||||||
// are actually located on the trait/impl itself, so we need to load
|
// 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
|
// all of the generics from there and then look for bounds that are
|
||||||
// applied to this associated type in question.
|
// applied to this associated type in question.
|
||||||
let def = cx.tcx.lookup_trait_def(did);
|
|
||||||
let predicates = cx.tcx.item_predicates(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| {
|
generics.where_predicates.iter().filter_map(|pred| {
|
||||||
let (name, self_type, trait_, bounds) = match *pred {
|
let (name, self_type, trait_, bounds) = match *pred {
|
||||||
WherePredicate::BoundPredicate {
|
WherePredicate::BoundPredicate {
|
||||||
|
@ -1927,7 +1926,7 @@ impl Clean<Item> for hir::StructField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
|
impl<'tcx> Clean<Item> for ty::FieldDef {
|
||||||
fn clean(&self, cx: &DocContext) -> Item {
|
fn clean(&self, cx: &DocContext) -> Item {
|
||||||
Item {
|
Item {
|
||||||
name: Some(self.name).clean(cx),
|
name: Some(self.name).clean(cx),
|
||||||
|
@ -1937,7 +1936,7 @@ impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
|
||||||
stability: get_stability(cx, self.did),
|
stability: get_stability(cx, self.did),
|
||||||
deprecation: get_deprecation(cx, self.did),
|
deprecation: get_deprecation(cx, self.did),
|
||||||
def_id: self.did,
|
def_id: self.did,
|
||||||
inner: StructFieldItem(self.unsubst_ty().clean(cx)),
|
inner: StructFieldItem(cx.tcx.item_type(self.did).clean(cx)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2084,13 +2083,13 @@ impl Clean<Item> for doctree::Variant {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
|
impl<'tcx> Clean<Item> for ty::VariantDef {
|
||||||
fn clean(&self, cx: &DocContext) -> Item {
|
fn clean(&self, cx: &DocContext) -> Item {
|
||||||
let kind = match self.ctor_kind {
|
let kind = match self.ctor_kind {
|
||||||
CtorKind::Const => VariantKind::CLike,
|
CtorKind::Const => VariantKind::CLike,
|
||||||
CtorKind::Fn => {
|
CtorKind::Fn => {
|
||||||
VariantKind::Tuple(
|
VariantKind::Tuple(
|
||||||
self.fields.iter().map(|f| f.unsubst_ty().clean(cx)).collect()
|
self.fields.iter().map(|f| cx.tcx.item_type(f.did).clean(cx)).collect()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CtorKind::Fictive => {
|
CtorKind::Fictive => {
|
||||||
|
@ -2106,7 +2105,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
|
||||||
def_id: field.did,
|
def_id: field.did,
|
||||||
stability: get_stability(cx, field.did),
|
stability: get_stability(cx, field.did),
|
||||||
deprecation: get_deprecation(cx, field.did),
|
deprecation: get_deprecation(cx, field.did),
|
||||||
inner: StructFieldItem(field.unsubst_ty().clean(cx))
|
inner: StructFieldItem(cx.tcx.item_type(field.did).clean(cx))
|
||||||
}
|
}
|
||||||
}).collect()
|
}).collect()
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue