1
Fork 0

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:
Niko Matsakis 2014-12-27 19:42:27 -05:00
parent 964a5fabb7
commit 2bbd2f9cea
14 changed files with 120 additions and 138 deletions

View file

@ -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' => {

View file

@ -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));

View file

@ -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),

View file

@ -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), _) => {

View file

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

View file

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

View file

@ -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);

View file

@ -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,

View file

@ -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;

View file

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

View file

@ -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[],

View file

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

View file

@ -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),
_ => {}
};

View file

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