rustc: simplify AdtDef by removing the field types and ty::ivar.

This commit is contained in:
Eduard-Mihai Burtescu 2016-11-25 01:33:29 +02:00
parent 3f338eed99
commit 07ff914be1
38 changed files with 199 additions and 404 deletions

View File

@ -110,7 +110,6 @@ pub enum DepNode<D: Clone + Debug> {
// predicates for an item wind up in `ItemSignature`).
AssociatedItems(D),
ItemSignature(D),
FieldTy(D),
SizedConstraint(D),
AssociatedItemDefIds(D),
InherentImpls(D),
@ -161,7 +160,6 @@ impl<D: Clone + Debug> DepNode<D> {
TypeckItemBody,
AssociatedItems,
ItemSignature,
FieldTy,
AssociatedItemDefIds,
InherentImpls,
TraitImpls,
@ -229,7 +227,6 @@ impl<D: Clone + Debug> DepNode<D> {
TransInlinedItem(ref d) => op(d).map(TransInlinedItem),
AssociatedItems(ref d) => op(d).map(AssociatedItems),
ItemSignature(ref d) => op(d).map(ItemSignature),
FieldTy(ref d) => op(d).map(FieldTy),
SizedConstraint(ref d) => op(d).map(SizedConstraint),
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
InherentImpls(ref d) => op(d).map(InherentImpls),

View File

@ -278,7 +278,7 @@ pub trait CrateStore<'tcx> {
-> ty::Generics<'tcx>;
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef;
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 inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
@ -425,7 +425,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
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
{ 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") }
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![] }

View File

@ -701,7 +701,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
// are properly handled.
self.walk_expr(with_expr);
fn contains_field_named(field: ty::FieldDef,
fn contains_field_named(field: &ty::FieldDef,
fields: &[hir::Field])
-> bool
{

View File

@ -462,7 +462,7 @@ pub enum TerminatorKind<'tcx> {
/// lvalue evaluates to some enum; jump depending on the branch
Switch {
discr: Lvalue<'tcx>,
adt_def: AdtDef<'tcx>,
adt_def: &'tcx AdtDef,
targets: Vec<BasicBlock>,
},
@ -866,7 +866,7 @@ pub enum ProjectionElem<'tcx, V> {
/// "Downcast" to a variant of an ADT. Currently, we only introduce
/// this for ADTs with more than one variant. It may be better to
/// 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
@ -1035,7 +1035,7 @@ pub enum AggregateKind<'tcx> {
/// The second field is variant number (discriminant), it's equal to 0
/// for struct and union expressions. The fourth field is active field
/// 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>),
}

View File

@ -25,7 +25,7 @@ pub enum LvalueTy<'tcx> {
Ty { ty: Ty<'tcx> },
/// Downcast to a particular variant of an enum.
Downcast { adt_def: AdtDef<'tcx>,
Downcast { adt_def: &'tcx AdtDef,
substs: &'tcx Substs<'tcx>,
variant_index: usize },
}

View File

@ -2557,7 +2557,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
(&ty::TyAdt(def, substs_a), &ty::TyAdt(_, substs_b)) => {
let fields = def
.all_fields()
.map(|f| f.unsubst_ty())
.map(|f| tcx.item_type(f.did))
.collect::<Vec<_>>();
// The last field of the structure has to exist and contain type parameters.

View File

@ -67,7 +67,7 @@ pub struct CtxtArenas<'tcx> {
// references
generics: TypedArena<ty::Generics<'tcx>>,
trait_def: TypedArena<ty::TraitDef>,
adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
adt_def: TypedArena<ty::AdtDef>,
mir: TypedArena<RefCell<Mir<'tcx>>>,
}
@ -420,6 +420,7 @@ pub struct GlobalCtxt<'tcx> {
pub impl_trait_refs: RefCell<DepTrackingMap<maps::ImplTraitRefs<'tcx>>>,
pub trait_defs: RefCell<DepTrackingMap<maps::TraitDefs<'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
/// associated generics and predicates.
@ -687,22 +688,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.global_interners.arenas.trait_def.alloc(def)
}
pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
// this will need a transmute when reverse-variance is removed
if let Some(prev) = self.adt_defs.borrow_mut().insert(did, adt_def) {
bug!("Tried to overwrite interned AdtDef: {:?}", prev)
}
}
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 alloc_adt_def(self,
did: DefId,
kind: AdtKind,
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_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
@ -798,6 +790,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
impl_trait_refs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
trait_defs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
adt_defs: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
adt_sized_constraint: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
generics: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
@ -1346,7 +1339,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
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
self.mk_ty(TyAdt(def, substs))
}

View File

@ -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>)")
}
}
}

View File

@ -40,7 +40,8 @@ dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tc
dep_map_ty! { AssociatedItemDefIds: AssociatedItemDefIds(DefId) -> Rc<Vec<DefId>> }
dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>> }
dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef }
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! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }

View File

@ -99,7 +99,6 @@ pub mod util;
mod contents;
mod context;
mod flags;
mod ivar;
mod structural_impls;
mod sty;
@ -1315,106 +1314,64 @@ bitflags! {
}
}
pub type AdtDef<'tcx> = &'tcx AdtDefData<'tcx, 'static>;
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> {
pub struct VariantDef {
/// The variant's DefId. If this is a tuple-like struct,
/// this is the DefId of the struct's ctor.
pub did: DefId,
pub name: Name, // struct's name if this is a struct
pub disr_val: Disr,
pub fields: Vec<FieldDefData<'tcx, 'container>>,
pub fields: Vec<FieldDef>,
pub ctor_kind: CtorKind,
}
pub struct FieldDefData<'tcx, 'container: 'tcx> {
pub struct FieldDef {
pub did: DefId,
pub name: Name,
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.
///
/// These are all interned (by intern_adt_def) into the adt_defs
/// table.
///
/// 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 struct AdtDef {
pub did: DefId,
pub variants: Vec<VariantDefData<'tcx, 'container>>,
pub variants: Vec<VariantDef>,
destructor: Cell<Option<DefId>>,
flags: Cell<AdtFlags>,
sized_constraint: ivar::TyIVar<'tcx, 'container>,
flags: Cell<AdtFlags>
}
impl<'tcx, 'container> PartialEq for AdtDefData<'tcx, 'container> {
// AdtDefData are always interned and this is part of TyS equality
impl PartialEq for AdtDef {
// AdtDef are always interned and this is part of TyS equality
#[inline]
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]
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> {
self.did.encode(s)
}
}
impl<'tcx> serialize::UseSpecializedDecodable for AdtDef<'tcx> {}
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())
})
}
}
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
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>,
did: DefId,
kind: AdtKind,
variants: Vec<VariantDefData<'gcx, 'container>>) -> Self {
variants: Vec<VariantDef>) -> Self {
let mut flags = AdtFlags::NO_ADT_FLAGS;
let attrs = tcx.get_attrs(did);
if attr::contains_name(&attrs, "fundamental") {
@ -1431,12 +1388,11 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
AdtKind::Union => flags = flags | AdtFlags::IS_UNION,
AdtKind::Struct => {}
}
AdtDefData {
AdtDef {
did: did,
variants: variants,
flags: Cell::new(flags),
destructor: Cell::new(None),
sized_constraint: ivar::TyIVar::new(),
}
}
@ -1447,6 +1403,20 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
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]
pub fn is_struct(&self) -> bool {
!self.is_union() && !self.is_enum()
@ -1526,7 +1496,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
/// Asserts this is a struct and returns the struct's unique
/// variant.
pub fn struct_variant(&self) -> &VariantDefData<'gcx, 'container> {
pub fn struct_variant(&self) -> &VariantDef {
assert!(!self.is_enum());
&self.variants[0]
}
@ -1539,14 +1509,8 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
/// Returns an iterator over all fields contained
/// by this ADT.
#[inline]
pub fn all_fields(&self) ->
iter::FlatMap<
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)
pub fn all_fields<'s>(&'s self) -> impl Iterator<Item = &'s FieldDef> {
self.variants.iter().flat_map(|v| v.fields.iter())
}
#[inline]
@ -1559,7 +1523,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
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
.iter()
.find(|v| v.did == vid)
@ -1573,7 +1537,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
.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 {
Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
@ -1596,9 +1560,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
None => NoDtor,
}
}
}
impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'tcx, 'container> {
/// Returns a simpler type such that `Self: Sized` if and only
/// if that type is Sized, or `TyErr` if this type is recursive.
///
@ -1617,19 +1579,9 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'tcx, 'container> {
/// Due to normalization being eager, this applies even if
/// the associated type is behind a pointer, e.g. issue #31299.
pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
match self.sized_constraint.get(DepNode::SizedConstraint(self.did)) {
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
}
self.calculate_sized_constraint_inner(tcx.global_tcx(), &mut Vec::new())
}
}
impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
/// Calculates the Sized-constraint.
///
/// As the Sized-constraint of enums can be a *set* of types,
@ -1645,42 +1597,41 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
/// such.
/// - a TyError, if a type contained itself. The representability
/// check should catch this case.
fn calculate_sized_constraint_inner(&'tcx self,
fn calculate_sized_constraint_inner(&self,
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
// DepNode::SizedConstraint as our current task.
let _task = tcx.dep_graph.in_task(dep_node());
if self.sized_constraint.untracked_get().is_some() {
// ---------------
// can skip the dep-graph read since we just pushed the task
return;
}
let _task = tcx.dep_graph.in_task(DepNode::SizedConstraint(self.did));
if stack.contains(&self) {
if stack.contains(&self.did) {
debug!("calculate_sized_constraint: {:?} is recursive", self);
// This should be reported as an error by `check_representable`.
//
// Consider the type as Sized in the meanwhile to avoid
// further errors.
self.sized_constraint.fulfill(dep_node(), tcx.types.err);
return;
tcx.adt_sized_constraint.borrow_mut().insert(self.did, tcx.types.err);
return tcx.types.err;
}
stack.push(self);
stack.push(self.did);
let tys : Vec<_> =
self.variants.iter().flat_map(|v| {
v.fields.last()
}).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();
let self_ = stack.pop().unwrap();
assert_eq!(self_, self);
assert_eq!(self_, self.did);
let ty = match tys.len() {
_ if tys.references_error() => tcx.types.err,
@ -1689,24 +1640,26 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
_ => 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) => {
debug!("calculate_sized_constraint: {:?} recurred", self);
assert_eq!(old_ty, tcx.types.err)
assert_eq!(old_ty, tcx.types.err);
old_ty
}
None => {
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(
&'tcx self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
stack: &mut Vec<AdtDefMaster<'tcx>>,
ty: Ty<'tcx>
) -> Vec<Ty<'tcx>> {
fn sized_constraint_for_ty(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
stack: &mut Vec<DefId>,
ty: Ty<'tcx>)
-> Vec<Ty<'tcx>> {
let result = match ty.sty {
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
@ -1728,12 +1681,9 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
TyAdt(adt, substs) => {
// recursive case
let adt = tcx.lookup_adt_def_master(adt.did);
adt.calculate_sized_constraint_inner(tcx, stack);
let adt_ty =
adt.sized_constraint
.unwrap(DepNode::SizedConstraint(adt.did))
.subst(tcx, substs);
adt.calculate_sized_constraint_inner(tcx, stack)
.subst(tcx, substs);
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
ty, adt_ty);
if let ty::TyTuple(ref tys) = adt_ty.sty {
@ -1782,16 +1732,11 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
}
}
impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
#[inline]
fn fields_iter(&self) -> slice::Iter<FieldDefData<'tcx, 'container>> {
self.fields.iter()
}
impl<'a, 'gcx, 'tcx> VariantDef {
#[inline]
pub fn find_field_named(&self,
name: ast::Name)
-> Option<&FieldDefData<'tcx, 'container>> {
-> Option<&FieldDef> {
self.fields.iter().find(|f| f.name == name)
}
@ -1803,55 +1748,32 @@ impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
}
#[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()
}
}
impl<'a, 'gcx, 'tcx> VariantDefData<'tcx, 'static> {
#[inline]
pub fn is_uninhabited_recurse(&'tcx self,
pub fn is_uninhabited_recurse(&self,
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
block: Option<NodeId>,
cx: TyCtxt<'a, 'gcx, 'tcx>,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
substs: &'tcx Substs<'tcx>,
is_union: bool) -> bool {
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 {
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> {
pub fn new(did: DefId,
name: Name,
vis: Visibility) -> Self {
FieldDefData {
did: did,
name: name,
vis: vis,
ty: ivar::TyIVar::new()
}
}
impl<'a, 'gcx, 'tcx> FieldDef {
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]
pub fn is_uninhabited_recurse(&'tcx self,
pub fn is_uninhabited_recurse(&self,
visited: &mut FxHashSet<(DefId, &'tcx Substs<'tcx>)>,
block: Option<NodeId>,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
@ -2301,7 +2223,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// Returns `ty::VariantDef` if `def` refers to a struct,
// 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 {
Def::Variant(did) | Def::VariantCtor(did, ..) => {
let enum_did = self.parent_def_id(did).unwrap();
@ -2403,21 +2325,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
)
}
/// Given the did of an ADT, return a master reference to its
/// definition. Unless you are planning on fulfilling the ADT's fields,
/// use lookup_adt_def instead.
pub fn lookup_adt_def_master(self, did: DefId) -> AdtDefMaster<'gcx> {
/// Given the did of an ADT, return a reference to its definition.
pub fn lookup_adt_def(self, did: DefId) -> &'gcx AdtDef {
lookup_locally_or_in_crate_store(
"adt_defs", did, &self.adt_defs,
|| 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)
|| self.sess.cstore.adt_def(self.global_tcx(), did))
}
/// Given the did of an item, returns its generics.

View File

@ -113,7 +113,7 @@ pub enum TypeVariants<'tcx> {
/// That is, even after substitution it is possible that there are type
/// variables. This happens when the `TyAdt` corresponds to an ADT
/// 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
/// special-cased internally. For example, it is possible to implicitly
@ -1228,7 +1228,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 {
TyAdt(adt, _) => Some(adt),
_ => None

View File

@ -365,7 +365,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// `adt` that do not strictly outlive the adt value itself.
/// (This allows programs to make cyclic structures without
/// 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() {
Some(dtor) => dtor,
None => return false
@ -767,7 +767,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 {
TyAdt(ty_def, _) => {
ty_def == def

View File

@ -440,7 +440,7 @@ impl fmt::Debug for ty::TraitDef {
}
}
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 {
ty::tls::with(|tcx| {
write!(f, "{}", tcx.item_path_str(self.did))

View File

@ -442,7 +442,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
fn move_paths_for_fields(&self,
base_lv: &Lvalue<'tcx>,
variant_path: MovePathIndex,
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
substs: &'tcx Substs<'tcx>)
-> Vec<(Lvalue<'tcx>, Option<MovePathIndex>)>
{
@ -619,7 +619,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
fn open_drop_for_variant<'a>(&mut self,
c: &DropCtxt<'a, 'tcx>,
drop_block: &mut Option<BasicBlock>,
adt: ty::AdtDef<'tcx>,
adt: &'tcx ty::AdtDef,
substs: &'tcx Substs<'tcx>,
variant_index: usize)
-> BasicBlock
@ -652,7 +652,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, '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 {
debug!("open_drop_for_adt({:?}, {:?}, {:?})", c, adt, substs);

View File

@ -223,10 +223,8 @@ pub enum Constructor {
Slice(usize),
}
impl Constructor {
fn variant_for_adt<'tcx, 'container, 'a>(&self,
adt: &'a ty::AdtDefData<'tcx, 'container>)
-> &'a ty::VariantDefData<'tcx, 'container> {
impl<'tcx> Constructor {
fn variant_for_adt(&self, adt: &'tcx ty::AdtDef) -> &'tcx ty::VariantDef {
match self {
&Variant(vid) => adt.variant_with_id(vid),
&Single => {

View File

@ -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
Variant {
adt_def: AdtDef<'tcx>,
adt_def: &'tcx AdtDef,
variant_index: usize,
subpatterns: Vec<FieldPattern<'tcx>>,
},
@ -487,32 +487,22 @@ impl<'tcx, T: PatternFoldable<'tcx>> PatternFoldable<'tcx> for Option<T> {
}
}
macro_rules! CopyImpls {
($($ty:ty),+) => {
macro_rules! CloneImpls {
(<$lt_tcx:tt> $($ty:ty),+) => {
$(
impl<'tcx> PatternFoldable<'tcx> for $ty {
fn super_fold_with<F: PatternFolder<'tcx>>(&self, _: &mut F) -> Self {
self.clone()
}
}
)+
}
}
macro_rules! TcxCopyImpls {
($($ty:ident),+) => {
$(
impl<'tcx> PatternFoldable<'tcx> for $ty<'tcx> {
fn super_fold_with<F: PatternFolder<'tcx>>(&self, _: &mut F) -> Self {
*self
impl<$lt_tcx> PatternFoldable<$lt_tcx> for $ty {
fn super_fold_with<F: PatternFolder<$lt_tcx>>(&self, _: &mut F) -> Self {
Clone::clone(self)
}
}
)+
}
}
CopyImpls!{ Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal }
TcxCopyImpls!{ Ty, BindingMode, AdtDef }
CloneImpls!{ <'tcx>
Span, Field, Mutability, ast::Name, ast::NodeId, usize, ConstVal,
Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef
}
impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> {
fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {

View File

@ -396,7 +396,7 @@ enum FfiResult {
/// expanded to cover NonZero raw pointers and newtypes.
/// FIXME: This duplicates code in trans.
fn is_repr_nullable_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def: ty::AdtDef<'tcx>,
def: &'tcx ty::AdtDef,
substs: &Substs<'tcx>)
-> bool {
if def.variants.len() == 2 {

View File

@ -116,7 +116,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
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.get_crate_data(def.krate).get_adt_def(def.index, tcx)

View File

@ -409,8 +409,8 @@ impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::BareFnTy<'tcx>> for DecodeContext<'a
}
}
impl<'a, 'tcx> SpecializedDecoder<ty::AdtDef<'tcx>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<ty::AdtDef<'tcx>, Self::Error> {
impl<'a, 'tcx> SpecializedDecoder<&'tcx ty::AdtDef> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<&'tcx ty::AdtDef, Self::Error> {
let def_id = DefId::decode(self)?;
Ok(self.tcx().lookup_adt_def(def_id))
}
@ -546,7 +546,7 @@ impl<'a, 'tcx> CrateMetadata {
fn get_variant(&self,
item: &Entry<'tcx>,
index: DefIndex)
-> (ty::VariantDefData<'tcx, 'tcx>, Option<DefIndex>) {
-> (ty::VariantDef, Option<DefIndex>) {
let data = match item.kind {
EntryKind::Variant(data) |
EntryKind::Struct(data) |
@ -554,28 +554,26 @@ impl<'a, 'tcx> CrateMetadata {
_ => bug!(),
};
let fields = item.children
.decode(self)
.map(|index| {
(ty::VariantDef {
did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
name: self.item_name(item),
fields: item.children.decode(self).map(|index| {
let f = self.entry(index);
ty::FieldDefData::new(self.local_def_id(index), self.item_name(&f), f.visibility)
})
.collect();
(ty::VariantDefData {
did: self.local_def_id(data.struct_ctor.unwrap_or(index)),
name: self.item_name(item),
fields: fields,
disr_val: ConstInt::Infer(data.disr),
ctor_kind: data.ctor_kind,
},
data.struct_ctor)
ty::FieldDef {
did: self.local_def_id(index),
name: self.item_name(&f),
vis: f.visibility
}
}).collect(),
disr_val: ConstInt::Infer(data.disr),
ctor_kind: data.ctor_kind,
}, data.struct_ctor)
}
pub fn get_adt_def(&self,
item_id: DefIndex,
tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> ty::AdtDefMaster<'tcx> {
-> &'tcx ty::AdtDef {
let item = self.entry(item_id);
let did = self.local_def_id(item_id);
let mut ctor_index = None;
@ -600,26 +598,10 @@ impl<'a, 'tcx> CrateMetadata {
_ => 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 {
// Make adt definition available through constructor id as well.
tcx.insert_adt_def(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);
}
tcx.adt_defs.borrow_mut().insert(self.local_def_id(ctor_index), adt);
}
adt

View File

@ -301,7 +301,7 @@ pub struct MatchPair<'pat, 'tcx:'pat> {
enum TestKind<'tcx> {
// test the branches of enum
Switch {
adt_def: AdtDef<'tcx>,
adt_def: &'tcx AdtDef,
variants: BitVector,
},

View File

@ -615,7 +615,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
fn candidate_after_variant_switch<'pat>(&mut self,
match_pair_index: usize,
adt_def: ty::AdtDef<'tcx>,
adt_def: &'tcx ty::AdtDef,
variant_index: usize,
subpatterns: &'pat [FieldPattern<'tcx>],
candidate: &Candidate<'pat, 'tcx>)

View File

@ -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.
fn field_refs<'tcx>(variant: VariantDef<'tcx>,
fn field_refs<'tcx>(variant: &'tcx VariantDef,
fields: &'tcx [hir::Field])
-> Vec<FieldExprRef<'tcx>>
{

View File

@ -155,11 +155,11 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
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()
}
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())
.map(Field::new)
.collect()

View File

@ -221,7 +221,7 @@ pub enum ExprKind<'tcx> {
fields: Vec<ExprRef<'tcx>>,
},
Adt {
adt_def: AdtDef<'tcx>,
adt_def: &'tcx AdtDef,
variant_index: usize,
substs: &'tcx Substs<'tcx>,
fields: Vec<FieldExprRef<'tcx>>,

View File

@ -405,7 +405,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
}
// 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) {
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
field.name, def.variant_descr(), self.tcx.item_path_str(def.did))

View File

@ -941,7 +941,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
ex: &ast::Expr,
path: &ast::Path,
fields: &Vec<ast::Field>,
variant: ty::VariantDef,
variant: &ty::VariantDef,
base: &Option<P<ast::Expr>>) {
self.write_sub_paths_truncated(path, false);

View File

@ -622,7 +622,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
pub fn get_field_ref_data(&self,
field_ref: &ast::Field,
variant: ty::VariantDef,
variant: &ty::VariantDef,
parent: NodeId)
-> Option<VariableRefData> {
let f = variant.field_named(field_ref.ident.node.name);

View File

@ -768,9 +768,10 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
}
ty::TyAdt(adt_def, substs) => {
for field in adt_def.all_fields() {
let field_type = scx.tcx().item_type(field.did);
let field_type = monomorphize::apply_param_substs(scx,
substs,
&field.unsubst_ty());
&field_type);
let field_type = glue::get_drop_glue_type(scx.tcx(), field_type);
if glue::type_needs_drop(scx.tcx(), field_type) {

View File

@ -879,7 +879,7 @@ impl<'tcx> MemberDescriptionFactory<'tcx> {
// Creates MemberDescriptions for the fields of a struct
struct StructMemberDescriptionFactory<'tcx> {
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
substs: &'tcx Substs<'tcx>,
is_simd: bool,
span: Span,
@ -1021,7 +1021,7 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
//=-----------------------------------------------------------------------------
struct UnionMemberDescriptionFactory<'tcx> {
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
substs: &'tcx Substs<'tcx>,
span: Span,
}
@ -1335,7 +1335,7 @@ enum EnumDiscriminantInfo {
fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
enum_type: Ty<'tcx>,
struct_def: &layout::Struct,
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
discriminant_info: EnumDiscriminantInfo,
containing_scope: DIScope,
span: Span)
@ -1354,7 +1354,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)
};
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)
}).collect::<Vec<_>>();

View File

@ -504,7 +504,7 @@ fn drop_structural_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
fn iter_variant<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
t: Ty<'tcx>,
av: adt::MaybeSizedValue,
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
substs: &Substs<'tcx>)
-> Block<'blk, 'tcx> {
let _icx = push_ctxt("iter_variant");

View File

@ -60,7 +60,7 @@ pub fn apply_param_substs<'a, 'tcx, T>(scx: &SharedCrateContext<'a, 'tcx>,
/// Returns the normalized type of a struct field
pub fn field_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_substs: &Substs<'tcx>,
f: ty::FieldDef<'tcx>)
f: &'tcx ty::FieldDef)
-> Ty<'tcx>
{
tcx.normalize_associated_type(&f.ty(tcx, param_substs))

View File

@ -626,7 +626,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
adt_ty: Ty<'tcx>,
pat_id: ast::NodeId,
span: Span,
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
fields: &'gcx [Spanned<hir::FieldPat>],
etc: bool) {
let tcx = self.tcx;

View File

@ -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,()>`
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,
substs: &Substs<'tcx>)
-> Ty<'tcx> {

View File

@ -1985,7 +1985,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Indifferent to privacy flags
pub fn field_ty(&self,
span: Span,
field: ty::FieldDef<'tcx>,
field: &'tcx ty::FieldDef,
substs: &Substs<'tcx>)
-> Ty<'tcx>
{
@ -3071,7 +3071,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
// 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>,
skip : Vec<InternedString>)
-> Option<Symbol> {
@ -3164,7 +3164,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn report_unknown_field(&self,
ty: Ty<'tcx>,
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
field: &hir::Field,
skip_fields: &[hir::Field],
kind_name: &str) {
@ -3208,7 +3208,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
adt_ty: Ty<'tcx>,
expr_id: ast::NodeId,
span: Span,
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
ast_fields: &'gcx [hir::Field],
check_completeness: bool) {
let tcx = self.tcx;
@ -3324,7 +3324,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn check_struct_path(&self,
qpath: &hir::QPath,
node_id: ast::NodeId)
-> Option<(ty::VariantDef<'tcx>, Ty<'tcx>)> {
-> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
let path_span = match *qpath {
hir::QPath::Resolved(_, ref path) => path.span,
hir::QPath::TypeRelative(ref qself, _) => qself.span

View File

@ -395,7 +395,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
.filter_map(|(i, f)| {
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
return None;
}

View File

@ -617,10 +617,10 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
struct_generics: &'tcx ty::Generics<'tcx>,
struct_predicates: &ty::GenericPredicates<'tcx>,
field: &hir::StructField,
ty_f: ty::FieldDefMaster<'tcx>)
ty_f: &'tcx ty::FieldDef)
{
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);
ccx.tcx.item_types.borrow_mut().insert(def_id, tt);
@ -732,7 +732,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
let generics = generics_of_def_id(ccx, def_id);
let predicates = predicates_of_item(ccx, it);
convert_enum_variant_types(ccx,
tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
tcx.lookup_adt_def(ccx.tcx.map.local_def_id(it.id)),
ty,
generics,
predicates,
@ -842,7 +842,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
let generics = generics_of_def_id(ccx, def_id);
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()) {
convert_field(ccx, generics, &predicates, f, ty_f)
@ -911,7 +911,7 @@ fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) {
fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
ctor_id: ast::NodeId,
variant: ty::VariantDef<'tcx>,
variant: &'tcx ty::VariantDef,
ty: Ty<'tcx>,
predicates: ty::GenericPredicates<'tcx>) {
let tcx = ccx.tcx;
@ -923,7 +923,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let inputs: Vec<_> =
variant.fields
.iter()
.map(|field| field.unsubst_ty())
.map(|field| tcx.item_type(field.did))
.collect();
let substs = mk_item_substs(&ccx.icx(&predicates),
ccx.tcx.map.span(ctor_id), def_id);
@ -943,7 +943,7 @@ fn convert_variant_ctor<'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>,
generics: &'tcx ty::Generics<'tcx>,
predicates: ty::GenericPredicates<'tcx>,
@ -971,7 +971,7 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
name: ast::Name,
disr_val: ty::Disr,
def: &hir::VariantData)
-> ty::VariantDefData<'tcx, 'tcx> {
-> ty::VariantDef {
let mut seen_fields: FxHashMap<ast::Name, Span> = FxHashMap();
let node_id = ccx.tcx.map.as_local_node_id(did).unwrap();
let fields = def.fields().iter().map(|f| {
@ -988,10 +988,13 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
seen_fields.insert(f.name, f.span);
}
ty::FieldDefData::new(fid, f.name,
ty::Visibility::from_hir(&f.vis, node_id, ccx.tcx))
ty::FieldDef {
did: fid,
name: f.name,
vis: ty::Visibility::from_hir(&f.vis, node_id, ccx.tcx)
}
}).collect();
ty::VariantDefData {
ty::VariantDef {
did: did,
name: name,
disr_val: disr_val,
@ -1003,29 +1006,34 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
it: &hir::Item,
def: &hir::VariantData)
-> ty::AdtDefMaster<'tcx>
-> &'tcx ty::AdtDef
{
let did = ccx.tcx.map.local_def_id(it.id);
// 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 variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name,
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 {
// 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
}
fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
it: &hir::Item,
def: &hir::VariantData)
-> ty::AdtDefMaster<'tcx>
-> &'tcx ty::AdtDef
{
let did = ccx.tcx.map.local_def_id(it.id);
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)
@ -1079,7 +1087,7 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
it: &hir::Item,
def: &hir::EnumDef)
-> ty::AdtDefMaster<'tcx>
-> &'tcx ty::AdtDef
{
let tcx = ccx.tcx;
let did = tcx.map.local_def_id(it.id);
@ -1107,7 +1115,10 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let did = tcx.map.local_def_id(v.node.data.id());
convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
}).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

View File

@ -92,7 +92,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
for field in tcx.lookup_adt_def(did).all_fields() {
self.add_constraints_from_ty(generics,
field.unsubst_ty(),
tcx.item_type(field.did),
self.covariant);
}
}

View File

@ -1942,7 +1942,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 {
Item {
name: Some(self.name).clean(cx),
@ -1952,7 +1952,7 @@ impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
stability: get_stability(cx, self.did),
deprecation: get_deprecation(cx, self.did),
def_id: self.did,
inner: StructFieldItem(self.unsubst_ty().clean(cx)),
inner: StructFieldItem(cx.tcx.item_type(self.did).clean(cx)),
}
}
}
@ -2099,13 +2099,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 {
let kind = match self.ctor_kind {
CtorKind::Const => VariantKind::CLike,
CtorKind::Fn => {
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 => {
@ -2121,7 +2121,7 @@ impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
def_id: field.did,
stability: get_stability(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()
})