Remove the def-id from type parameters. Having this def-id was bad for several reasons:
1. Produced more unique types than is necessary. This increases memory consumption. 2. Linking the type parameter to its definition *seems* like a good idea, but it encourages reliance on the bounds listing. 3. It made pretty-printing harder and in particular was causing bad error messages when errors occurred before the `TypeParameterDef` entries were fully stored.
This commit is contained in:
parent
964a5fabb7
commit
2bbd2f9cea
14 changed files with 120 additions and 138 deletions
|
@ -420,13 +420,13 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
|
|||
return ty::mk_trait(tcx, trait_ref, bounds);
|
||||
}
|
||||
'p' => {
|
||||
let did = parse_def(st, TypeParameter, |x,y| conv(x,y));
|
||||
debug!("parsed ty_param: did={}", did);
|
||||
assert_eq!(next(st), '[');
|
||||
let index = parse_u32(st);
|
||||
assert_eq!(next(st), '|');
|
||||
let space = parse_param_space(st);
|
||||
assert_eq!(next(st), '|');
|
||||
return ty::mk_param(tcx, space, index, did);
|
||||
let name = token::intern(parse_str(st, ']')[]);
|
||||
return ty::mk_param(tcx, space, index, name);
|
||||
}
|
||||
'~' => return ty::mk_uniq(tcx, parse_ty(st, |x,y| conv(x,y))),
|
||||
'*' => return ty::mk_ptr(tcx, parse_mt(st, |x,y| conv(x,y))),
|
||||
|
@ -507,7 +507,7 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
|
|||
'P' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let trait_ref = parse_trait_ref(st, |x,y| conv(x,y));
|
||||
let name = token::str_to_ident(parse_str(st, ']').as_slice()).name;
|
||||
let name = token::intern(parse_str(st, ']').as_slice());
|
||||
return ty::mk_projection(tcx, trait_ref, name);
|
||||
}
|
||||
'e' => {
|
||||
|
|
|
@ -135,8 +135,8 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
|
|||
ty::ty_infer(_) => {
|
||||
cx.diag.handler().bug("cannot encode inference variable types");
|
||||
}
|
||||
ty::ty_param(ParamTy {space, idx: id, def_id: did}) => {
|
||||
mywrite!(w, "p{}|{}|{}|", (cx.ds)(did), id, space.to_uint())
|
||||
ty::ty_param(ParamTy {space, idx, name}) => {
|
||||
mywrite!(w, "p[{}|{}|{}]", idx, space.to_uint(), token::get_name(name))
|
||||
}
|
||||
ty::ty_struct(def, substs) => {
|
||||
mywrite!(w, "a[{}|", (cx.ds)(def));
|
||||
|
|
|
@ -448,7 +448,7 @@ impl tr for def::Def {
|
|||
def::DefAssociatedPath(def::TyParamProvenance::FromParam(did), ident) =>
|
||||
def::DefAssociatedPath(def::TyParamProvenance::FromParam(did.tr(dcx)), ident),
|
||||
def::DefPrimTy(p) => def::DefPrimTy(p),
|
||||
def::DefTyParam(s, did, v) => def::DefTyParam(s, did.tr(dcx), v),
|
||||
def::DefTyParam(s, index, def_id, n) => def::DefTyParam(s, index, def_id.tr(dcx), n),
|
||||
def::DefUse(did) => def::DefUse(did.tr(dcx)),
|
||||
def::DefUpvar(nid1, nid2, nid3) => {
|
||||
def::DefUpvar(dcx.tr_id(nid1),
|
||||
|
|
|
@ -39,7 +39,7 @@ pub enum Def {
|
|||
DefAssociatedPath(TyParamProvenance, ast::Ident),
|
||||
DefTrait(ast::DefId),
|
||||
DefPrimTy(ast::PrimTy),
|
||||
DefTyParam(ParamSpace, ast::DefId, u32),
|
||||
DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
|
||||
DefUse(ast::DefId),
|
||||
DefUpvar(ast::NodeId, // id of closed over local
|
||||
ast::NodeId, // expr node that creates the closure
|
||||
|
@ -130,7 +130,7 @@ impl Def {
|
|||
DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |
|
||||
DefForeignMod(id) | DefStatic(id, _) |
|
||||
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
|
||||
DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
|
||||
DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
|
||||
DefMethod(id, _, _) | DefConst(id) |
|
||||
DefAssociatedPath(TyParamProvenance::FromSelf(id), _) |
|
||||
DefAssociatedPath(TyParamProvenance::FromParam(id), _) => {
|
||||
|
|
|
@ -86,7 +86,7 @@ use syntax::ast::{Visibility};
|
|||
use syntax::ast_util::{mod, is_local, lit_is_str, local_def, PostExpansionMethod};
|
||||
use syntax::attr::{mod, AttrMetaMethods};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::{mod, InternedString};
|
||||
use syntax::parse::token::{mod, InternedString, special_idents};
|
||||
use syntax::{ast, ast_map};
|
||||
|
||||
pub type Disr = u64;
|
||||
|
@ -1079,7 +1079,7 @@ pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
|
|||
pub struct ParamTy {
|
||||
pub space: subst::ParamSpace,
|
||||
pub idx: u32,
|
||||
pub def_id: DefId
|
||||
pub name: ast::Name,
|
||||
}
|
||||
|
||||
/// A [De Bruijn index][dbi] is a standard means of representing
|
||||
|
@ -2775,17 +2775,19 @@ pub fn mk_infer<'tcx>(cx: &ctxt<'tcx>, it: InferTy) -> Ty<'tcx> {
|
|||
mk_t(cx, ty_infer(it))
|
||||
}
|
||||
|
||||
pub fn mk_param<'tcx>(cx: &ctxt<'tcx>, space: subst::ParamSpace,
|
||||
n: u32, k: DefId) -> Ty<'tcx> {
|
||||
mk_t(cx, ty_param(ParamTy { space: space, idx: n, def_id: k }))
|
||||
pub fn mk_param<'tcx>(cx: &ctxt<'tcx>,
|
||||
space: subst::ParamSpace,
|
||||
index: u32,
|
||||
name: ast::Name) -> Ty<'tcx> {
|
||||
mk_t(cx, ty_param(ParamTy { space: space, idx: index, name: name }))
|
||||
}
|
||||
|
||||
pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId) -> Ty<'tcx> {
|
||||
mk_param(cx, subst::SelfSpace, 0, did)
|
||||
pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
|
||||
mk_param(cx, subst::SelfSpace, 0, special_idents::type_self.name)
|
||||
}
|
||||
|
||||
pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'tcx> {
|
||||
mk_param(cx, def.space, def.index, def.def_id)
|
||||
mk_param(cx, def.space, def.index, def.name)
|
||||
}
|
||||
|
||||
pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) }
|
||||
|
@ -2854,21 +2856,21 @@ pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
|
|||
impl ParamTy {
|
||||
pub fn new(space: subst::ParamSpace,
|
||||
index: u32,
|
||||
def_id: ast::DefId)
|
||||
name: ast::Name)
|
||||
-> ParamTy {
|
||||
ParamTy { space: space, idx: index, def_id: def_id }
|
||||
ParamTy { space: space, idx: index, name: name }
|
||||
}
|
||||
|
||||
pub fn for_self(trait_def_id: ast::DefId) -> ParamTy {
|
||||
ParamTy::new(subst::SelfSpace, 0, trait_def_id)
|
||||
pub fn for_self() -> ParamTy {
|
||||
ParamTy::new(subst::SelfSpace, 0, special_idents::type_self.name)
|
||||
}
|
||||
|
||||
pub fn for_def(def: &TypeParameterDef) -> ParamTy {
|
||||
ParamTy::new(def.space, def.index, def.def_id)
|
||||
ParamTy::new(def.space, def.index, def.name)
|
||||
}
|
||||
|
||||
pub fn to_ty<'tcx>(self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
|
||||
ty::mk_param(tcx, self.space, self.idx, self.def_id)
|
||||
ty::mk_param(tcx, self.space, self.idx, self.name)
|
||||
}
|
||||
|
||||
pub fn is_self(&self) -> bool {
|
||||
|
@ -6256,8 +6258,9 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
|
|||
}
|
||||
ty_param(p) => {
|
||||
byte!(20);
|
||||
hash!(p.space);
|
||||
hash!(p.idx);
|
||||
did(state, p.def_id);
|
||||
hash!(token::get_name(p.name));
|
||||
}
|
||||
ty_open(_) => byte!(22),
|
||||
ty_infer(_) => unreachable!(),
|
||||
|
@ -6312,17 +6315,11 @@ pub fn construct_parameter_environment<'tcx>(
|
|||
|
||||
// map T => T
|
||||
let mut types = VecPerParamSpace::empty();
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
push_types_from_defs(tcx, &mut types, space,
|
||||
generics.types.get_slice(space));
|
||||
}
|
||||
push_types_from_defs(tcx, &mut types, generics.types.as_slice());
|
||||
|
||||
// map bound 'a => free 'a
|
||||
let mut regions = VecPerParamSpace::empty();
|
||||
for &space in subst::ParamSpace::all().iter() {
|
||||
push_region_params(&mut regions, space, free_id,
|
||||
generics.regions.get_slice(space));
|
||||
}
|
||||
push_region_params(&mut regions, free_id, generics.regions.as_slice());
|
||||
|
||||
let free_substs = Substs {
|
||||
types: types,
|
||||
|
@ -6359,27 +6356,22 @@ pub fn construct_parameter_environment<'tcx>(
|
|||
};
|
||||
|
||||
fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
|
||||
space: subst::ParamSpace,
|
||||
free_id: ast::NodeId,
|
||||
region_params: &[RegionParameterDef])
|
||||
{
|
||||
for r in region_params.iter() {
|
||||
regions.push(space, ty::free_region_from_def(free_id, r));
|
||||
regions.push(r.space, ty::free_region_from_def(free_id, r));
|
||||
}
|
||||
}
|
||||
|
||||
fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
types: &mut subst::VecPerParamSpace<Ty<'tcx>>,
|
||||
space: subst::ParamSpace,
|
||||
defs: &[TypeParameterDef<'tcx>]) {
|
||||
for (i, def) in defs.iter().enumerate() {
|
||||
debug!("construct_parameter_environment(): push_types_from_defs: \
|
||||
space={} def={} index={}",
|
||||
space,
|
||||
def.repr(tcx),
|
||||
i);
|
||||
let ty = ty::mk_param(tcx, space, i as u32, def.def_id);
|
||||
types.push(space, ty);
|
||||
for def in defs.iter() {
|
||||
debug!("construct_parameter_environment(): push_types_from_defs: def={}",
|
||||
def.repr(tcx));
|
||||
let ty = ty::mk_param_from_def(tcx, def);
|
||||
types.push(def.space, ty);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1328,17 +1328,8 @@ impl<'tcx> Repr<'tcx> for ty::ExplicitSelfCategory {
|
|||
}
|
||||
|
||||
impl<'tcx> UserString<'tcx> for ParamTy {
|
||||
fn user_string(&self, tcx: &ctxt) -> String {
|
||||
let id = self.idx;
|
||||
let did = self.def_id;
|
||||
let ident = match tcx.ty_param_defs.borrow().get(&did.node) {
|
||||
Some(def) => token::get_name(def.name).get().to_string(),
|
||||
|
||||
// This can only happen when a type mismatch error happens and
|
||||
// the actual type has more type parameters than the expected one.
|
||||
None => format!("<generic #{}>", id),
|
||||
};
|
||||
ident
|
||||
fn user_string(&self, _tcx: &ctxt) -> String {
|
||||
format!("{}", token::get_name(self.name))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3906,7 +3906,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
// If the def is a ty param, and came from the parent
|
||||
// item, it's ok
|
||||
match def {
|
||||
DefTyParam(_, did, _) if {
|
||||
DefTyParam(_, _, did, _) if {
|
||||
self.def_map.borrow().get(&did.node).cloned()
|
||||
== Some(DefTyParamBinder(item_id))
|
||||
} => {} // ok
|
||||
|
@ -3959,7 +3959,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
// If the def is a ty param, and came from the parent
|
||||
// item, it's ok
|
||||
match def {
|
||||
DefTyParam(_, did, _) if {
|
||||
DefTyParam(_, _, did, _) if {
|
||||
self.def_map.borrow().get(&did.node).cloned()
|
||||
== Some(DefTyParamBinder(item_id))
|
||||
} => {} // ok
|
||||
|
@ -4265,8 +4265,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
seen_bindings.insert(name);
|
||||
|
||||
let def_like = DlDef(DefTyParam(space,
|
||||
index as u32,
|
||||
local_def(type_parameter.id),
|
||||
index as u32));
|
||||
name));
|
||||
// Associate this type parameter with
|
||||
// the item that bound it
|
||||
self.record_def(type_parameter.id,
|
||||
|
@ -5161,7 +5162,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
path.span) {
|
||||
Some((def, last_private)) => {
|
||||
match def {
|
||||
DefTyParam(_, did, _) => {
|
||||
DefTyParam(_, _, did, _) => {
|
||||
let def = DefAssociatedPath(TyParamProvenance::FromParam(did),
|
||||
path.segments.last()
|
||||
.unwrap().identifier);
|
||||
|
|
|
@ -1118,17 +1118,16 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
def::DefTy(did, _) | def::DefStruct(did) => {
|
||||
ast_path_to_ty(this, rscope, did, path).ty
|
||||
}
|
||||
def::DefTyParam(space, id, n) => {
|
||||
def::DefTyParam(space, index, _, name) => {
|
||||
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
|
||||
ty::mk_param(tcx, space, n, id)
|
||||
ty::mk_param(tcx, space, index, name)
|
||||
}
|
||||
def::DefSelfTy(id) => {
|
||||
def::DefSelfTy(_) => {
|
||||
// n.b.: resolve guarantees that the this type only appears in a
|
||||
// trait, which we rely upon in various places when creating
|
||||
// substs
|
||||
check_path_args(tcx, path, NO_TPS | NO_REGIONS);
|
||||
let did = ast_util::local_def(id);
|
||||
ty::mk_self_type(tcx, did)
|
||||
ty::mk_self_type(tcx)
|
||||
}
|
||||
def::DefMod(id) => {
|
||||
tcx.sess.span_fatal(ast_ty.span,
|
||||
|
|
|
@ -5065,7 +5065,7 @@ pub fn type_scheme_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
def::DefAssociatedTy(..) |
|
||||
def::DefAssociatedPath(..) |
|
||||
def::DefPrimTy(_) |
|
||||
def::DefTyParam(..)=> {
|
||||
def::DefTyParam(..) => {
|
||||
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found type");
|
||||
}
|
||||
def::DefMod(..) | def::DefForeignMod(..) => {
|
||||
|
@ -5635,7 +5635,8 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
|
||||
fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
|
||||
ty::mk_param(ccx.tcx, subst::FnSpace, n, local_def(0))
|
||||
let name = token::intern(format!("P{}", n).as_slice());
|
||||
ty::mk_param(ccx.tcx, subst::FnSpace, n, name)
|
||||
}
|
||||
|
||||
let tcx = ccx.tcx;
|
||||
|
|
|
@ -1848,11 +1848,9 @@ fn param_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
|||
// well-formed, then, A must be lower-bounded by `'a`, but we
|
||||
// don't know that this holds from first principles.
|
||||
for &(ref r, ref p) in rcx.region_param_pairs.iter() {
|
||||
debug!("param_ty={}/{} p={}/{}",
|
||||
debug!("param_ty={} p={}",
|
||||
param_ty.repr(rcx.tcx()),
|
||||
param_ty.def_id,
|
||||
p.repr(rcx.tcx()),
|
||||
p.def_id);
|
||||
p.repr(rcx.tcx()));
|
||||
if param_ty == *p {
|
||||
param_bounds.push(*r);
|
||||
}
|
||||
|
|
|
@ -349,7 +349,7 @@ fn collect_trait_methods<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
(*trait_generics).clone());
|
||||
|
||||
let (fty, explicit_self_category) = {
|
||||
let trait_self_ty = ty::mk_self_type(ccx.tcx, local_def(trait_id));
|
||||
let trait_self_ty = ty::mk_self_type(ccx.tcx);
|
||||
astconv::ty_of_method(ccx,
|
||||
*m_unsafety,
|
||||
trait_self_ty,
|
||||
|
@ -639,10 +639,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
trait_def.repr(ccx.tcx()));
|
||||
|
||||
for trait_method in trait_methods.iter() {
|
||||
let self_type = ty::mk_param(ccx.tcx,
|
||||
subst::SelfSpace,
|
||||
0,
|
||||
local_def(it.id));
|
||||
let self_type = ty::mk_self_type(tcx);
|
||||
match *trait_method {
|
||||
ast::RequiredMethod(ref type_method) => {
|
||||
let rscope = BindingRscope::new();
|
||||
|
@ -668,8 +665,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
}
|
||||
|
||||
// Run convert_methods on the provided methods.
|
||||
let untransformed_rcvr_ty = ty::mk_self_type(tcx,
|
||||
local_def(it.id));
|
||||
let untransformed_rcvr_ty = ty::mk_self_type(tcx);
|
||||
convert_methods(ccx,
|
||||
TraitContainer(local_def(it.id)),
|
||||
trait_methods.iter().filter_map(|m| match *m {
|
||||
|
@ -834,7 +830,7 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
}
|
||||
};
|
||||
|
||||
let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, it.id, generics));
|
||||
let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
|
||||
|
||||
let ty_generics = ty_generics_for_trait(ccx,
|
||||
it.id,
|
||||
|
@ -844,7 +840,7 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
assert_eq!(mk_item_substs(ccx, &ty_generics), substs);
|
||||
|
||||
let self_param_ty = ty::ParamTy::for_self(def_id);
|
||||
let self_param_ty = ty::ParamTy::for_self();
|
||||
|
||||
let bounds = compute_bounds(ccx,
|
||||
self_param_ty.to_ty(ccx.tcx),
|
||||
|
@ -878,7 +874,6 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
return trait_def;
|
||||
|
||||
fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
trait_id: ast::NodeId,
|
||||
generics: &ast::Generics)
|
||||
-> subst::Substs<'tcx>
|
||||
{
|
||||
|
@ -899,12 +894,11 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, def)| ty::mk_param(ccx.tcx, subst::TypeSpace,
|
||||
i as u32, local_def(def.id)))
|
||||
i as u32, def.ident.name))
|
||||
.collect();
|
||||
|
||||
// ...and also create the `Self` parameter.
|
||||
let self_ty =
|
||||
ty::mk_param(ccx.tcx, subst::SelfSpace, 0, local_def(trait_id));
|
||||
let self_ty = ty::mk_self_type(ccx.tcx);
|
||||
|
||||
subst::Substs::new_trait(types, regions, Vec::new(), self_ty)
|
||||
}
|
||||
|
@ -1311,7 +1305,7 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
|
|||
None => { }
|
||||
}
|
||||
|
||||
let param_ty = ty::ParamTy::new(space, index, local_def(param.id));
|
||||
let param_ty = ty::ParamTy::new(space, index, param.ident.name);
|
||||
let bounds = compute_bounds(this,
|
||||
param_ty.to_ty(this.tcx()),
|
||||
param.bounds[],
|
||||
|
|
|
@ -479,8 +479,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
let did = ast_util::local_def(item.id);
|
||||
let tcx = self.terms_cx.tcx;
|
||||
|
||||
debug!("visit_item item={}",
|
||||
item.repr(tcx));
|
||||
|
||||
match item.node {
|
||||
ast::ItemEnum(ref enum_definition, _) => {
|
||||
let generics = &ty::lookup_item_type(tcx, did).generics;
|
||||
|
||||
// Hack: If we directly call `ty::enum_variants`, it
|
||||
// annoyingly takes it upon itself to run off and
|
||||
// evaluate the discriminants eagerly (*grumpy* that's
|
||||
|
@ -497,17 +502,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
&**ast_variant,
|
||||
/*discriminant*/ 0);
|
||||
for arg_ty in variant.args.iter() {
|
||||
self.add_constraints_from_ty(*arg_ty, self.covariant);
|
||||
self.add_constraints_from_ty(generics, *arg_ty, self.covariant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemStruct(..) => {
|
||||
let generics = &ty::lookup_item_type(tcx, did).generics;
|
||||
let struct_fields = ty::lookup_struct_fields(tcx, did);
|
||||
for field_info in struct_fields.iter() {
|
||||
assert_eq!(field_info.id.krate, ast::LOCAL_CRATE);
|
||||
let field_ty = ty::node_id_to_type(tcx, field_info.id.node);
|
||||
self.add_constraints_from_ty(field_ty, self.covariant);
|
||||
self.add_constraints_from_ty(generics, field_ty, self.covariant);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,7 +522,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
for trait_item in trait_items.iter() {
|
||||
match *trait_item {
|
||||
ty::MethodTraitItem(ref method) => {
|
||||
self.add_constraints_from_sig(&method.fty.sig,
|
||||
self.add_constraints_from_sig(&method.generics,
|
||||
&method.fty.sig,
|
||||
self.covariant);
|
||||
}
|
||||
ty::TypeTraitItem(_) => {}
|
||||
|
@ -713,8 +720,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Adds constraints appropriate for an instance of `ty` appearing
|
||||
/// in a context with ambient variance `variance`
|
||||
/// in a context with the generics defined in `generics` and
|
||||
/// ambient variance `variance`
|
||||
fn add_constraints_from_ty(&mut self,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
variance: VarianceTermPtr<'a>) {
|
||||
debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx()));
|
||||
|
@ -732,40 +741,40 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
|
||||
ty::ty_rptr(region, ref mt) => {
|
||||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(*region, contra);
|
||||
self.add_constraints_from_mt(mt, variance);
|
||||
self.add_constraints_from_region(generics, *region, contra);
|
||||
self.add_constraints_from_mt(generics, mt, variance);
|
||||
}
|
||||
|
||||
ty::ty_uniq(typ) | ty::ty_vec(typ, _) | ty::ty_open(typ) => {
|
||||
self.add_constraints_from_ty(typ, variance);
|
||||
self.add_constraints_from_ty(generics, typ, variance);
|
||||
}
|
||||
|
||||
ty::ty_ptr(ref mt) => {
|
||||
self.add_constraints_from_mt(mt, variance);
|
||||
self.add_constraints_from_mt(generics, mt, variance);
|
||||
}
|
||||
|
||||
ty::ty_tup(ref subtys) => {
|
||||
for &subty in subtys.iter() {
|
||||
self.add_constraints_from_ty(subty, variance);
|
||||
self.add_constraints_from_ty(generics, subty, variance);
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_enum(def_id, substs) |
|
||||
ty::ty_struct(def_id, substs) => {
|
||||
let item_type = ty::lookup_item_type(self.tcx(), def_id);
|
||||
let generics = &item_type.generics;
|
||||
|
||||
// All type parameters on enums and structs should be
|
||||
// in the TypeSpace.
|
||||
assert!(generics.types.is_empty_in(subst::SelfSpace));
|
||||
assert!(generics.types.is_empty_in(subst::FnSpace));
|
||||
assert!(generics.regions.is_empty_in(subst::SelfSpace));
|
||||
assert!(generics.regions.is_empty_in(subst::FnSpace));
|
||||
assert!(item_type.generics.types.is_empty_in(subst::SelfSpace));
|
||||
assert!(item_type.generics.types.is_empty_in(subst::FnSpace));
|
||||
assert!(item_type.generics.regions.is_empty_in(subst::SelfSpace));
|
||||
assert!(item_type.generics.regions.is_empty_in(subst::FnSpace));
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
generics,
|
||||
def_id,
|
||||
generics.types.get_slice(subst::TypeSpace),
|
||||
generics.regions.get_slice(subst::TypeSpace),
|
||||
item_type.generics.types.get_slice(subst::TypeSpace),
|
||||
item_type.generics.regions.get_slice(subst::TypeSpace),
|
||||
substs,
|
||||
variance);
|
||||
}
|
||||
|
@ -773,11 +782,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
ty::ty_projection(ref data) => {
|
||||
let trait_ref = &data.trait_ref;
|
||||
let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id);
|
||||
let generics = &trait_def.generics;
|
||||
self.add_constraints_from_substs(
|
||||
generics,
|
||||
trait_ref.def_id,
|
||||
generics.types.as_slice(),
|
||||
generics.regions.as_slice(),
|
||||
trait_def.generics.types.as_slice(),
|
||||
trait_def.generics.regions.as_slice(),
|
||||
&trait_ref.substs,
|
||||
variance);
|
||||
}
|
||||
|
@ -785,27 +794,28 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
ty::ty_trait(ref data) => {
|
||||
let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx().types.err);
|
||||
let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id());
|
||||
let generics = &trait_def.generics;
|
||||
|
||||
// Traits never declare region parameters in the self
|
||||
// space nor anything in the fn space.
|
||||
assert!(generics.regions.is_empty_in(subst::SelfSpace));
|
||||
assert!(generics.types.is_empty_in(subst::FnSpace));
|
||||
assert!(generics.regions.is_empty_in(subst::FnSpace));
|
||||
assert!(trait_def.generics.regions.is_empty_in(subst::SelfSpace));
|
||||
assert!(trait_def.generics.types.is_empty_in(subst::FnSpace));
|
||||
assert!(trait_def.generics.regions.is_empty_in(subst::FnSpace));
|
||||
|
||||
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
|
||||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(data.bounds.region_bound, contra);
|
||||
self.add_constraints_from_region(generics, data.bounds.region_bound, contra);
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
generics,
|
||||
trait_ref.def_id(),
|
||||
generics.types.get_slice(subst::TypeSpace),
|
||||
generics.regions.get_slice(subst::TypeSpace),
|
||||
trait_def.generics.types.get_slice(subst::TypeSpace),
|
||||
trait_def.generics.regions.get_slice(subst::TypeSpace),
|
||||
trait_ref.substs(),
|
||||
variance);
|
||||
}
|
||||
|
||||
ty::ty_param(ty::ParamTy { ref def_id, .. }) => {
|
||||
ty::ty_param(ref data) => {
|
||||
let def_id = generics.types.get(data.space, data.idx).def_id;
|
||||
assert_eq!(def_id.krate, ast::LOCAL_CRATE);
|
||||
match self.terms_cx.inferred_map.get(&def_id.node) {
|
||||
Some(&index) => {
|
||||
|
@ -826,14 +836,14 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
..
|
||||
}) =>
|
||||
{
|
||||
self.add_constraints_from_sig(sig, variance);
|
||||
self.add_constraints_from_sig(generics, sig, variance);
|
||||
}
|
||||
|
||||
ty::ty_closure(box ty::ClosureTy { ref sig,
|
||||
store: ty::RegionTraitStore(region, _), .. }) => {
|
||||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(region, contra);
|
||||
self.add_constraints_from_sig(sig, variance);
|
||||
self.add_constraints_from_region(generics, region, contra);
|
||||
self.add_constraints_from_sig(generics, sig, variance);
|
||||
}
|
||||
|
||||
ty::ty_infer(..) | ty::ty_err => {
|
||||
|
@ -849,6 +859,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
/// Adds constraints appropriate for a nominal type (enum, struct,
|
||||
/// object, etc) appearing in a context with ambient variance `variance`
|
||||
fn add_constraints_from_substs(&mut self,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
def_id: ast::DefId,
|
||||
type_param_defs: &[ty::TypeParameterDef<'tcx>],
|
||||
region_param_defs: &[ty::RegionParameterDef],
|
||||
|
@ -862,7 +873,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
p.space, p.index as uint);
|
||||
let variance_i = self.xform(variance, variance_decl);
|
||||
let substs_ty = *substs.types.get(p.space, p.index as uint);
|
||||
self.add_constraints_from_ty(substs_ty, variance_i);
|
||||
self.add_constraints_from_ty(generics, substs_ty, variance_i);
|
||||
}
|
||||
|
||||
for p in region_param_defs.iter() {
|
||||
|
@ -871,27 +882,29 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
RegionParam, p.space, p.index as uint);
|
||||
let variance_i = self.xform(variance, variance_decl);
|
||||
let substs_r = *substs.regions().get(p.space, p.index as uint);
|
||||
self.add_constraints_from_region(substs_r, variance_i);
|
||||
self.add_constraints_from_region(generics, substs_r, variance_i);
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds constraints appropriate for a function with signature
|
||||
/// `sig` appearing in a context with ambient variance `variance`
|
||||
fn add_constraints_from_sig(&mut self,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
sig: &ty::PolyFnSig<'tcx>,
|
||||
variance: VarianceTermPtr<'a>) {
|
||||
let contra = self.contravariant(variance);
|
||||
for &input in sig.0.inputs.iter() {
|
||||
self.add_constraints_from_ty(input, contra);
|
||||
self.add_constraints_from_ty(generics, input, contra);
|
||||
}
|
||||
if let ty::FnConverging(result_type) = sig.0.output {
|
||||
self.add_constraints_from_ty(result_type, variance);
|
||||
self.add_constraints_from_ty(generics, result_type, variance);
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds constraints appropriate for a region appearing in a
|
||||
/// context with ambient variance `variance`
|
||||
fn add_constraints_from_region(&mut self,
|
||||
_generics: &ty::Generics<'tcx>,
|
||||
region: ty::Region,
|
||||
variance: VarianceTermPtr<'a>) {
|
||||
match region {
|
||||
|
@ -925,16 +938,17 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
/// Adds constraints appropriate for a mutability-type pair
|
||||
/// appearing in a context with ambient variance `variance`
|
||||
fn add_constraints_from_mt(&mut self,
|
||||
generics: &ty::Generics<'tcx>,
|
||||
mt: &ty::mt<'tcx>,
|
||||
variance: VarianceTermPtr<'a>) {
|
||||
match mt.mutbl {
|
||||
ast::MutMutable => {
|
||||
let invar = self.invariant(variance);
|
||||
self.add_constraints_from_ty(mt.ty, invar);
|
||||
self.add_constraints_from_ty(generics, mt.ty, invar);
|
||||
}
|
||||
|
||||
ast::MutImmutable => {
|
||||
self.add_constraints_from_ty(mt.ty, variance);
|
||||
self.add_constraints_from_ty(generics, mt.ty, variance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@ use syntax::ast_util::PostExpansionMethod;
|
|||
use syntax::attr;
|
||||
use syntax::attr::{AttributeMethods, AttrMetaMethods};
|
||||
use syntax::codemap::{DUMMY_SP, Pos, Spanned};
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::parse::token;
|
||||
use syntax::parse::token::{mod, InternedString, special_idents};
|
||||
use syntax::ptr::P;
|
||||
|
||||
use rustc_trans::back::link;
|
||||
|
@ -1200,11 +1199,9 @@ pub enum Type {
|
|||
},
|
||||
// I have no idea how to usefully use this.
|
||||
TyParamBinder(ast::NodeId),
|
||||
/// For parameterized types, so the consumer of the JSON don't go looking
|
||||
/// for types which don't exist anywhere.
|
||||
Generic(ast::DefId),
|
||||
/// For references to self
|
||||
Self(ast::DefId),
|
||||
/// For parameterized types, so the consumer of the JSON don't go
|
||||
/// looking for types which don't exist anywhere.
|
||||
Generic(String),
|
||||
/// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
|
||||
Primitive(PrimitiveType),
|
||||
Closure(Box<ClosureDecl>),
|
||||
|
@ -1485,13 +1482,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::ty_param(ref p) => {
|
||||
if p.space == subst::SelfSpace {
|
||||
Self(p.def_id)
|
||||
} else {
|
||||
Generic(p.def_id)
|
||||
}
|
||||
}
|
||||
ty::ty_param(ref p) => Generic(token::get_name(p.name).to_string()),
|
||||
|
||||
ty::ty_unboxed_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
|
||||
|
||||
|
@ -2276,7 +2267,9 @@ fn resolve_type(cx: &DocContext,
|
|||
};
|
||||
|
||||
match def {
|
||||
def::DefSelfTy(i) => return Self(ast_util::local_def(i)),
|
||||
def::DefSelfTy(..) => {
|
||||
return Generic(token::get_name(special_idents::type_self.name).to_string());
|
||||
}
|
||||
def::DefPrimTy(p) => match p {
|
||||
ast::TyStr => return Primitive(Str),
|
||||
ast::TyBool => return Primitive(Bool),
|
||||
|
@ -2294,7 +2287,7 @@ fn resolve_type(cx: &DocContext,
|
|||
ast::TyFloat(ast::TyF32) => return Primitive(F32),
|
||||
ast::TyFloat(ast::TyF64) => return Primitive(F64),
|
||||
},
|
||||
def::DefTyParam(_, i, _) => return Generic(i),
|
||||
def::DefTyParam(_, _, _, n) => return Generic(token::get_name(n).to_string()),
|
||||
def::DefTyParamBinder(i) => return TyParamBinder(i),
|
||||
_ => {}
|
||||
};
|
||||
|
|
|
@ -435,15 +435,14 @@ impl fmt::Show for clean::Type {
|
|||
clean::TyParamBinder(id) => {
|
||||
f.write(cache().typarams[ast_util::local_def(id)].as_bytes())
|
||||
}
|
||||
clean::Generic(did) => {
|
||||
f.write(cache().typarams[did].as_bytes())
|
||||
clean::Generic(ref name) => {
|
||||
f.write(name.as_bytes())
|
||||
}
|
||||
clean::ResolvedPath{ did, ref typarams, ref path } => {
|
||||
try!(resolved_path(f, did, path, false));
|
||||
tybounds(f, typarams)
|
||||
}
|
||||
clean::Infer => write!(f, "_"),
|
||||
clean::Self(..) => f.write("Self".as_bytes()),
|
||||
clean::Primitive(prim) => primitive_link(f, prim, prim.to_string()),
|
||||
clean::Closure(ref decl) => {
|
||||
write!(f, "{style}{lifetimes}|{args}|{bounds}{arrow}",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue