rustc: store type parameter defaults outside of ty::Generics.
This commit is contained in:
parent
1572bf104d
commit
e8d01ea4c7
34 changed files with 394 additions and 385 deletions
|
|
@ -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
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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") }
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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>> }
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue