From 2bbd2f9ceafb86614b431cff4184f6e8ce7c973f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 27 Dec 2014 19:42:27 -0500 Subject: [PATCH] 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. --- src/librustc/metadata/tydecode.rs | 8 +-- src/librustc/metadata/tyencode.rs | 4 +- src/librustc/middle/astencode.rs | 2 +- src/librustc/middle/def.rs | 4 +- src/librustc/middle/ty.rs | 60 ++++++++----------- src/librustc/util/ppaux.rs | 13 +--- src/librustc_resolve/lib.rs | 9 +-- src/librustc_typeck/astconv.rs | 9 ++- src/librustc_typeck/check/mod.rs | 5 +- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/collect.rs | 22 +++---- src/librustc_typeck/variance.rs | 86 ++++++++++++++++----------- src/librustdoc/clean/mod.rs | 25 +++----- src/librustdoc/html/format.rs | 5 +- 14 files changed, 120 insertions(+), 138 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 7dccc49dcbbd..88c7ccf1b1e3 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -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' => { diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index b6d05882dce2..30746f51a8fe 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -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)); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 0b78f2b1cfce..a9c4f0ddd8c2 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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), diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index 023182df3365..59fd41b5d29e 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -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), _) => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 98539b4d1526..6225a0f3fba1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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>; 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, - 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>, - 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); } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 3e7b24ac93f9..ee1432bc953d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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!("", id), - }; - ident + fn user_string(&self, _tcx: &ctxt) -> String { + format!("{}", token::get_name(self.name)) } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7f01bf087381..52bd096eb83d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 26fadb0dfb10..477171051640 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4bc1246d3935..139ef010d212 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 1da8852c9b23..d01b79068aa2 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b311f10c0a32..1187baa9a9ce 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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[], diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index c3a3993b66b7..2914895aa7a7 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -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` 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); } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5063ce36019d..b4bfaa9afdab 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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), @@ -1485,13 +1482,7 @@ impl<'tcx> Clean 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), _ => {} }; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 585183e2af75..dc264a5b5aa0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -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}",