rustc: store type parameter defaults outside of ty::Generics.

This commit is contained in:
Eduard-Mihai Burtescu 2017-01-25 22:01:11 +02:00
parent 1572bf104d
commit e8d01ea4c7
34 changed files with 394 additions and 385 deletions

View file

@ -525,7 +525,7 @@ impl<'a> LoweringContext<'a> {
return n;
}
assert!(!def_id.is_local());
let (n, _) = self.sess.cstore.item_generics_own_param_counts(def_id);
let n = self.sess.cstore.item_generics(def_id).regions.len();
self.type_def_lifetime_params.insert(def_id, n);
n
});

View file

@ -1197,16 +1197,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// as the substitutions for the default, `(T, U)`.
pub fn type_var_for_def(&self,
span: Span,
def: &ty::TypeParameterDef<'tcx>,
def: &ty::TypeParameterDef,
substs: &[Kind<'tcx>])
-> Ty<'tcx> {
let default = def.default.map(|default| {
type_variable::Default {
let default = if def.has_default {
let default = self.tcx.item_type(def.def_id);
Some(type_variable::Default {
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
def_id: def.default_def_id
}
});
def_id: def.def_id
})
} else {
None
};
let ty_var_id = self.type_variables

View file

@ -28,7 +28,6 @@ use hir::map as hir_map;
use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData};
use hir::svh::Svh;
use middle::lang_items;
use middle::resolve_lifetime::ObjectLifetimeDefault;
use ty::{self, Ty, TyCtxt};
use mir::Mir;
use session::Session;
@ -182,11 +181,7 @@ pub trait CrateStore<'tcx> {
-> ty::GenericPredicates<'tcx>;
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::GenericPredicates<'tcx>;
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::Generics<'tcx>;
fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize);
fn item_generics_object_lifetime_defaults(&self, def: DefId)
-> Vec<ObjectLifetimeDefault>;
fn item_generics(&self, def: DefId) -> ty::Generics;
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) -> &'tcx ty::AdtDef;
@ -335,13 +330,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
-> ty::GenericPredicates<'tcx> { bug!("item_predicates") }
fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") }
fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> ty::Generics<'tcx> { bug!("item_generics") }
fn item_generics_own_param_counts(&self, def: DefId) -> (usize, usize)
{ bug!("item_generics_own_param_counts") }
fn item_generics_object_lifetime_defaults(&self, def: DefId)
-> Vec<ObjectLifetimeDefault>
{ bug!("item_generics_object_lifetime_defaults") }
fn item_generics(&self, def: DefId) -> ty::Generics { bug!("item_generics") }
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef
{ bug!("trait_def") }

View file

@ -995,7 +995,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} else {
let cstore = &self.sess.cstore;
self.xcrate_object_lifetime_defaults.entry(def_id).or_insert_with(|| {
cstore.item_generics_object_lifetime_defaults(def_id)
cstore.item_generics(def_id).types.into_iter().map(|def| {
def.object_lifetime_default
}).collect()
})
};
unsubst.iter().map(|set| {

View file

@ -64,7 +64,7 @@ pub struct GlobalArenas<'tcx> {
layout: TypedArena<Layout>,
// references
generics: TypedArena<ty::Generics<'tcx>>,
generics: TypedArena<ty::Generics>,
trait_def: TypedArena<ty::TraitDef>,
adt_def: TypedArena<ty::AdtDef>,
mir: TypedArena<RefCell<Mir<'tcx>>>,
@ -467,9 +467,6 @@ pub struct GlobalCtxt<'tcx> {
// Cache for the type-contents routine. FIXME -- track deps?
pub tc_cache: RefCell<FxHashMap<Ty<'tcx>, ty::contents::TypeContents>>,
// FIXME no dep tracking, but we should be able to remove this
pub ty_param_defs: RefCell<NodeMap<ty::TypeParameterDef<'tcx>>>,
// FIXME dep tracking -- should be harmless enough
pub normalized_cache: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
@ -646,15 +643,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}
pub fn type_parameter_def(self,
node_id: NodeId)
-> ty::TypeParameterDef<'tcx>
{
self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
}
pub fn alloc_generics(self, generics: ty::Generics<'gcx>)
-> &'gcx ty::Generics<'gcx> {
pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
self.global_arenas.generics.alloc(generics)
}
@ -785,7 +774,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
tc_cache: RefCell::new(FxHashMap()),
associated_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
associated_item_def_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
ty_param_defs: RefCell::new(NodeMap()),
normalized_cache: RefCell::new(FxHashMap()),
inhabitedness_cache: RefCell::new(FxHashMap()),
lang_items: lang_items,

View file

@ -10,7 +10,7 @@
use hir::def_id::DefId;
use infer::type_variable;
use ty::{self, BoundRegion, Region, Ty, TyCtxt};
use ty::{self, BoundRegion, DefIdTree, Region, Ty, TyCtxt};
use std::fmt;
use syntax::abi;
@ -287,8 +287,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
db.span_note(span, "a default was defined here...");
}
None => {
let item_def_id = self.parent(expected.def_id).unwrap();
db.note(&format!("a default is defined on `{}`",
self.item_path_str(expected.def_id)));
self.item_path_str(item_def_id)));
}
}
@ -301,8 +302,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
db.span_note(span, "a second default was defined here...");
}
None => {
let item_def_id = self.parent(found.def_id).unwrap();
db.note(&format!("a second default is defined on `{}`",
self.item_path_str(found.def_id)));
self.item_path_str(item_def_id)));
}
}

View file

@ -35,7 +35,7 @@ macro_rules! dep_map_ty {
dep_map_ty! { AssociatedItems: AssociatedItems(DefId) -> ty::AssociatedItem }
dep_map_ty! { Types: ItemSignature(DefId) -> Ty<'tcx> }
dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics<'tcx> }
dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics }
dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
dep_map_ty! { AssociatedItemDefIds: AssociatedItemDefIds(DefId) -> Rc<Vec<DefId>> }

View file

@ -19,9 +19,10 @@ use dep_graph::{self, DepNode};
use hir::{map as hir_map, FreevarMap, TraitMap};
use middle;
use hir::def::{Def, CtorKind, ExportMap};
use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
use middle::resolve_lifetime::ObjectLifetimeDefault;
use mir::Mir;
use traits;
use ty;
@ -33,6 +34,7 @@ use util::nodemap::{NodeSet, NodeMap, FxHashMap};
use serialize::{self, Encodable, Encoder};
use std::borrow::Cow;
use std::cell::{Cell, RefCell, Ref};
use std::collections::BTreeMap;
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::rc::Rc;
@ -585,13 +587,13 @@ pub enum IntVarValue {
UintType(ast::UintTy),
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct TypeParameterDef<'tcx> {
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct TypeParameterDef {
pub name: Name,
pub def_id: DefId,
pub index: u32,
pub default_def_id: DefId, // for use in error reporing about defaults
pub default: Option<Ty<'tcx>>,
pub has_default: bool,
pub object_lifetime_default: ObjectLifetimeDefault,
/// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
/// on generic parameter `T`, asserts data behind the parameter
@ -628,16 +630,21 @@ impl RegionParameterDef {
/// Information about the formal type/lifetime parameters associated
/// with an item or method. Analogous to hir::Generics.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Generics<'tcx> {
pub struct Generics {
pub parent: Option<DefId>,
pub parent_regions: u32,
pub parent_types: u32,
pub regions: Vec<RegionParameterDef>,
pub types: Vec<TypeParameterDef<'tcx>>,
pub types: Vec<TypeParameterDef>,
/// Reverse map to each `TypeParameterDef`'s `index` field, from
/// `def_id.index` (`def_id.krate` is the same as the item's).
pub type_param_to_index: BTreeMap<DefIndex, u32>,
pub has_self: bool,
}
impl<'tcx> Generics<'tcx> {
impl Generics {
pub fn parent_count(&self) -> usize {
self.parent_regions as usize + self.parent_types as usize
}
@ -651,10 +658,12 @@ impl<'tcx> Generics<'tcx> {
}
pub fn region_param(&self, param: &EarlyBoundRegion) -> &RegionParameterDef {
assert_eq!(self.parent_count(), 0);
&self.regions[param.index as usize - self.has_self as usize]
}
pub fn type_param(&self, param: &ParamTy) -> &TypeParameterDef<'tcx> {
pub fn type_param(&self, param: &ParamTy) -> &TypeParameterDef {
assert_eq!(self.parent_count(), 0);
&self.types[param.idx as usize - self.has_self as usize - self.regions.len()]
}
}
@ -2319,10 +2328,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
/// Given the did of an item, returns its generics.
pub fn item_generics(self, did: DefId) -> &'gcx Generics<'gcx> {
pub fn item_generics(self, did: DefId) -> &'gcx Generics {
lookup_locally_or_in_crate_store(
"generics", did, &self.generics,
|| self.alloc_generics(self.sess.cstore.item_generics(self.global_tcx(), did)))
|| self.alloc_generics(self.sess.cstore.item_generics(did)))
}
/// Given the did of an item, returns its full set of predicates.

View file

@ -353,7 +353,7 @@ macro_rules! CopyImpls {
}
}
CopyImpls! { (), hir::Unsafety, abi::Abi, ty::RegionParameterDef }
CopyImpls! { (), hir::Unsafety, abi::Abi }
impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
@ -716,40 +716,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::TypeParameterDef {
name: self.name,
def_id: self.def_id,
index: self.index,
default: self.default.fold_with(folder),
default_def_id: self.default_def_id,
pure_wrt_drop: self.pure_wrt_drop,
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.default.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::Generics {
parent: self.parent,
parent_regions: self.parent_regions,
parent_types: self.parent_types,
regions: self.regions.fold_with(folder),
types: self.types.fold_with(folder),
has_self: self.has_self,
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.regions.visit_with(visitor) || self.types.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::GenericPredicates {

View file

@ -184,7 +184,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
mut mk_type: FT)
-> &'tcx Substs<'tcx>
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> {
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
let defs = tcx.item_generics(def_id);
let mut substs = Vec::with_capacity(defs.count());
Substs::fill_item(&mut substs, tcx, defs, &mut mk_region, &mut mk_type);
@ -198,7 +198,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
mut mk_type: FT)
-> &'tcx Substs<'tcx>
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx>
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx>
{
let defs = tcx.item_generics(def_id);
let mut result = Vec::with_capacity(defs.count());
@ -209,11 +209,11 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
defs: &ty::Generics<'tcx>,
defs: &ty::Generics,
mk_region: &mut FR,
mk_type: &mut FT)
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> {
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
if let Some(def_id) = defs.parent {
let parent_defs = tcx.item_generics(def_id);
@ -223,11 +223,11 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
fn fill_single<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
defs: &ty::Generics<'tcx>,
defs: &ty::Generics,
mk_region: &mut FR,
mk_type: &mut FT)
where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> &'tcx ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &[Kind<'tcx>]) -> Ty<'tcx> {
FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> {
// Handle Self first, before all regions.
let mut types = defs.types.iter();
if defs.parent.is_none() && defs.has_self {
@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
tcx.mk_substs(target_substs.iter().chain(&self[defs.own_count()..]).cloned())
}
pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics<'tcx>)
pub fn truncate_to(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, generics: &ty::Generics)
-> &'tcx Substs<'tcx> {
tcx.mk_substs(self.iter().take(generics.count()).cloned())
}

View file

@ -137,11 +137,14 @@ pub fn parameterized(f: &mut fmt::Formatter,
}
if !verbose {
if generics.types.last().map_or(false, |def| def.default.is_some()) {
if generics.types.last().map_or(false, |def| def.has_default) {
if let Some(substs) = tcx.lift(&substs) {
let tps = substs.types().rev().skip(child_types);
for (def, actual) in generics.types.iter().rev().zip(tps) {
if def.default.subst(tcx, substs) != Some(actual) {
if !def.has_default {
break;
}
if tcx.item_type(def.def_id).subst(tcx, substs) != actual {
break;
}
num_supplied_defaults += 1;
@ -326,7 +329,7 @@ impl<'tcx> fmt::Display for &'tcx ty::Slice<ty::ExistentialPredicate<'tcx>> {
}
}
impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
impl fmt::Debug for ty::TypeParameterDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TypeParameterDef({}, {:?}, {})",
self.name,