diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 21fccd2c613..9a6375719c1 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -82,7 +82,6 @@ use hir::def::Def; use hir::def_id::DefId; use infer::{self, TypeOrigin}; use middle::region; -use ty::subst; use ty::{self, TyCtxt, TypeFoldable}; use ty::{Region, ReFree}; use ty::error::TypeError; @@ -1369,7 +1368,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> { let generics = self.tcx.lookup_generics(did); let expected = - generics.regions.len(subst::TypeSpace) as u32; + generics.regions.len() as u32; let lifetimes = path.segments.last().unwrap().parameters.lifetimes(); let mut insert = Vec::new(); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 77c1137c6c3..77d7d5115ef 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -271,14 +271,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let def = self.tcx.lookup_trait_def(trait_ref.def_id); let trait_str = def.trait_ref.to_string(); if let Some(ref istring) = item.value_str() { - let mut generic_map = def.generics.types.iter_enumerated() - .map(|(param, i, gen)| { - (gen.name.as_str().to_string(), - trait_ref.substs.types.get(param, i) - .to_string()) - }).collect::>(); - generic_map.insert("Self".to_string(), - trait_ref.self_ty().to_string()); + let generic_map = def.generics.types.iter().map(|param| { + (param.name.as_str().to_string(), + trait_ref.substs.type_for_def(param).to_string()) + }).collect::>(); let parser = Parser::new(&istring); let mut errored = false; let err: String = parser.filter_map(|p| { diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 11cf759859c..25d2df8fded 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -20,7 +20,6 @@ use super::elaborate_predicates; use hir::def_id::DefId; -use ty::subst; use traits; use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; use std::rc::Rc; @@ -266,7 +265,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } // We can't monomorphize things like `fn foo(...)`. - if !method.generics.types.is_empty_in(subst::FnSpace) { + if !method.generics.types.is_empty() { return Some(MethodViolationCode::Generic); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 96537904d36..689f2ad02c9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -757,33 +757,14 @@ impl RegionParameterDef { /// with an item or method. Analogous to hir::Generics. #[derive(Clone, Debug)] pub struct Generics<'tcx> { - pub types: VecPerParamSpace>, - pub regions: VecPerParamSpace, + pub parent: Option, + pub parent_regions: u32, + pub parent_types: u32, + pub regions: Vec, + pub types: Vec>, pub has_self: bool, } -impl<'tcx> Generics<'tcx> { - pub fn empty() -> Generics<'tcx> { - Generics { - types: VecPerParamSpace::empty(), - regions: VecPerParamSpace::empty(), - has_self: false, - } - } - - pub fn is_empty(&self) -> bool { - self.types.is_empty() && self.regions.is_empty() - } - - pub fn has_type_params(&self, space: subst::ParamSpace) -> bool { - !self.types.is_empty_in(space) - } - - pub fn has_region_params(&self, space: subst::ParamSpace) -> bool { - !self.regions.is_empty_in(space) - } -} - /// Bounds on generics. #[derive(Clone)] pub struct GenericPredicates<'tcx> { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 9021b0587a0..248d5d9062d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -832,20 +832,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef { } } -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 { - types: self.types.fold_with(folder), - regions: self.regions.fold_with(folder), - has_self: self.has_self - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.types.visit_with(visitor) || self.regions.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 { diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 2f95baa5625..594d15ad5f7 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -89,42 +89,55 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region, FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> { let defs = tcx.lookup_generics(def_id); + let num_regions = defs.parent_regions as usize + defs.regions.len(); + let num_types = defs.parent_types as usize + defs.types.len(); let mut substs = Substs { - types: VecPerParamSpace { - type_limit: 0, - content: Vec::with_capacity(defs.types.content.len()) - }, regions: VecPerParamSpace { type_limit: 0, - content: Vec::with_capacity(defs.regions.content.len()) + content: Vec::with_capacity(num_regions) + }, + types: VecPerParamSpace { + type_limit: 0, + content: Vec::with_capacity(num_types) } }; - for &space in &ParamSpace::all() { - for def in defs.regions.get_slice(space) { - assert_eq!(def.space, space); + substs.fill_item(tcx, defs, &mut mk_region, &mut mk_type); - let region = mk_region(def, &substs); - substs.regions.content.push(region); + Substs::new(tcx, substs.types, substs.regions) + } - if space == TypeSpace { - substs.regions.type_limit += 1; - } - } + fn fill_item(&mut self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + defs: &ty::Generics<'tcx>, + mk_region: &mut FR, + mk_type: &mut FT) + where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region, + FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> { + if let Some(def_id) = defs.parent { + let parent_defs = tcx.lookup_generics(def_id); + self.fill_item(tcx, parent_defs, mk_region, mk_type); + } - for def in defs.types.get_slice(space) { - assert_eq!(def.space, space); + for def in &defs.regions { + let region = mk_region(def, self); + self.regions.content.push(region); - let ty = mk_type(def, &substs); - substs.types.content.push(ty); - - if space == TypeSpace { - substs.types.type_limit += 1; - } + if def.space == TypeSpace { + self.regions.type_limit += 1; + assert_eq!(self.regions.content.len(), self.regions.type_limit); } } - Substs::new(tcx, substs.types, substs.regions) + for def in &defs.types { + let ty = mk_type(def, self); + self.types.content.push(ty); + + if def.space == TypeSpace { + self.types.type_limit += 1; + assert_eq!(self.types.content.len(), self.types.type_limit); + } + } } pub fn is_noop(&self) -> bool { @@ -149,16 +162,14 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { target_substs: &Substs<'tcx>) -> &'tcx Substs<'tcx> { let defs = tcx.lookup_generics(source_ancestor); - assert_eq!(self.types.len(TypeSpace), defs.types.len(TypeSpace)); + assert_eq!(self.types.len(TypeSpace), defs.types.len()); assert_eq!(target_substs.types.len(FnSpace), 0); - assert_eq!(defs.types.len(FnSpace), 0); - assert_eq!(self.regions.len(TypeSpace), defs.regions.len(TypeSpace)); + assert_eq!(self.regions.len(TypeSpace), defs.regions.len()); assert_eq!(target_substs.regions.len(FnSpace), 0); - assert_eq!(defs.regions.len(FnSpace), 0); let Substs { mut types, mut regions } = target_substs.clone(); - types.content.extend(&self.types.as_full_slice()[defs.types.content.len()..]); - regions.content.extend(&self.regions.as_full_slice()[defs.regions.content.len()..]); + types.content.extend(&self.types.as_full_slice()[defs.types.len()..]); + regions.content.extend(&self.regions.as_full_slice()[defs.regions.len()..]); Substs::new(tcx, types, regions) } } @@ -597,8 +608,8 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> { -> ty::TraitRef<'tcx> { let Substs { mut types, mut regions } = substs.clone(); let defs = tcx.lookup_generics(trait_id); - types.content.truncate(defs.types.type_limit); - regions.content.truncate(defs.regions.type_limit); + types.content.truncate(defs.types.len()); + regions.content.truncate(defs.regions.len()); ty::TraitRef { def_id: trait_id, diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 800ad865208..a62ee37613e 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -73,13 +73,15 @@ pub fn parameterized(f: &mut fmt::Formatter, let mut has_self = false; let (fn_trait_kind, item_name) = ty::tls::with(|tcx| { verbose = tcx.sess.verbose(); - let generics = tcx.lookup_generics(did); + let mut generics = tcx.lookup_generics(did); + if let Some(def_id) = generics.parent { + generics = tcx.lookup_generics(def_id); + } if !verbose { - let ty_params = generics.types.get_slice(subst::TypeSpace); - if ty_params.last().map_or(false, |def| def.default.is_some()) { + if generics.types.last().map_or(false, |def| def.default.is_some()) { if let Some(substs) = tcx.lift(&substs) { let tps = substs.types.get_slice(subst::TypeSpace); - for (def, actual) in ty_params.iter().zip(tps).rev() { + for (def, actual) in generics.types.iter().zip(tps).rev() { if def.default.subst(tcx, substs) != Some(actual) { break; } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 1e74b3c1ef4..0cde9b48d6f 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -620,9 +620,9 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, if let Some(impl_item) = impl_item_opt { if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { encode_attributes(rbml_w, &impl_item.attrs); - let scheme = ecx.tcx.lookup_item_type(m.def_id); - let any_types = !scheme.generics.types.is_empty(); - let needs_inline = any_types || is_default_impl || + let generics = ecx.tcx.lookup_generics(m.def_id); + let types = generics.parent_types as usize + generics.types.len(); + let needs_inline = types > 0 || is_default_impl || attr::requests_inline(&impl_item.attrs); if needs_inline || sig.constness == hir::Constness::Const { encode_inlined_item(ecx, diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs index 82d050a1de9..e8e3679a60c 100644 --- a/src/librustc_metadata/tydecode.rs +++ b/src/librustc_metadata/tydecode.rs @@ -149,9 +149,29 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> { } pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> { - let regions = self.parse_vec_per_param_space(|this| this.parse_region_param_def()); - let types = self.parse_vec_per_param_space(|this| this.parse_type_param_def()); + let parent = self.parse_opt(|this| this.parse_def()); + let parent_regions = self.parse_u32(); + assert_eq!(self.next(), '|'); + let parent_types = self.parse_u32(); + + let mut regions = vec![]; + assert_eq!(self.next(), '['); + while self.peek() != ']' { + regions.push(self.parse_region_param_def()); + } + assert_eq!(self.next(), ']'); + + let mut types = vec![]; + assert_eq!(self.next(), '['); + while self.peek() != ']' { + types.push(self.parse_type_param_def()); + } + assert_eq!(self.next(), ']'); + self.tcx.alloc_generics(ty::Generics { + parent: parent, + parent_regions: parent_regions, + parent_types: parent_types, regions: regions, types: types, has_self: self.next() == 'S' diff --git a/src/librustc_metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs index 130d1548582..27907596ca7 100644 --- a/src/librustc_metadata/tyencode.rs +++ b/src/librustc_metadata/tyencode.rs @@ -274,10 +274,21 @@ pub fn enc_substs<'a, 'tcx>(w: &mut Cursor>, cx: &ctxt<'a, 'tcx>, pub fn enc_generics<'a, 'tcx>(w: &mut Cursor>, cx: &ctxt<'a, 'tcx>, generics: &ty::Generics<'tcx>) { - enc_vec_per_param_space(w, cx, &generics.regions, - |w, cx, r| enc_region_param_def(w, cx, r)); - enc_vec_per_param_space(w, cx, &generics.types, - |w, cx, ty| enc_type_param_def(w, cx, ty)); + enc_opt(w, generics.parent, |w, def_id| { + write!(w, "{}|", (cx.ds)(cx.tcx, def_id)); + }); + write!(w, "{}|{}[", + generics.parent_regions, + generics.parent_types); + + for r in &generics.regions { + enc_region_param_def(w, cx, r) + } + write!(w, "]["); + for t in &generics.types { + enc_type_param_def(w, cx, t); + } + write!(w, "]"); if generics.has_self { write!(w, "S"); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index ee5d1d11fa0..f190fbeb6fe 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -2470,8 +2470,8 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet { hir_map::NodeImplItem(&hir::ImplItem { node: hir::ImplItemKind::Method(..), .. }) => { let def_id = tcx.map.local_def_id(id); - let scheme = tcx.lookup_item_type(def_id); - scheme.generics.types.is_empty() + let generics = tcx.lookup_generics(def_id); + generics.parent_types == 0 && generics.types.is_empty() } _ => false diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 82c86928783..76910304eeb 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -195,7 +195,7 @@ use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; use rustc::middle::lang_items::{ExchangeFreeFnLangItem, ExchangeMallocFnLangItem}; use rustc::traits; -use rustc::ty::subst::{self, Substs, Subst}; +use rustc::ty::subst::{Substs, Subst}; use rustc::ty::{self, TypeFoldable, TyCtxt}; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::mir::repr as mir; @@ -1219,17 +1219,16 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id_to_string(tcx, impl_def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { - let default_impls = tcx.provided_trait_methods(trait_ref.def_id); let callee_substs = tcx.erase_regions(&trait_ref.substs); let overridden_methods: FnvHashSet<_> = items.iter() .map(|item| item.name) .collect(); - for default_impl in default_impls { - if overridden_methods.contains(&default_impl.name) { + for method in tcx.provided_trait_methods(trait_ref.def_id) { + if overridden_methods.contains(&method.name) { continue; } - if default_impl.generics.has_type_params(subst::FnSpace) { + if !method.generics.types.is_empty() { continue; } @@ -1242,7 +1241,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, callee_substs, impl_def_id, impl_substs, - default_impl.name); + method.name); assert!(mth.is_provided); @@ -1251,10 +1250,10 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, continue; } - if can_have_local_instance(tcx, default_impl.def_id) { + if can_have_local_instance(tcx, method.def_id) { let empty_substs = tcx.erase_regions(&mth.substs); let item = create_fn_trans_item(tcx, - default_impl.def_id, + method.def_id, callee_substs, empty_substs); output.push(item); diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 963cc09e1ab..684628e9a40 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -381,10 +381,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Again, only create type information if full debuginfo is enabled let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo { - generics.types.as_full_slice().iter().enumerate().map(|(i, param)| { - let actual_type = cx.tcx().normalize_associated_type(&actual_types[i]); + let names = get_type_parameter_names(cx, generics); + actual_types.iter().zip(names).map(|(ty, name)| { + let actual_type = cx.tcx().normalize_associated_type(ty); let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); - let name = CString::new(param.name.as_str().as_bytes()).unwrap(); + let name = CString::new(name.as_str().as_bytes()).unwrap(); unsafe { llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), @@ -403,6 +404,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return create_DIArray(DIB(cx), &template_params[..]); } + fn get_type_parameter_names<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, + generics: &ty::Generics<'tcx>) + -> Vec { + let mut names = generics.parent.map_or(vec![], |def_id| { + get_type_parameter_names(cx, cx.tcx().lookup_generics(def_id)) + }); + names.extend(generics.types.iter().map(|param| param.name)); + names + } + fn get_containing_scope_and_span<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>, instance: Instance<'tcx>) -> (DIScope, Span) { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 109cfd2abf6..a452b55a7d3 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -429,7 +429,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { bug!("ErrorReported returned, but no errors reports?") } }; - let expected_num_region_params = decl_generics.regions.len(TypeSpace); + let expected_num_region_params = decl_generics.regions.len(); let supplied_num_region_params = lifetimes.len(); let regions = if expected_num_region_params == supplied_num_region_params { lifetimes.iter().map(|l| ast_region_to_region(tcx, l)).collect() @@ -454,8 +454,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // Check the number of type parameters supplied by the user. if let Some(num_provided) = num_types_provided { - let ty_param_defs = decl_generics.types.get_slice(TypeSpace); - let ty_param_defs = &ty_param_defs[self_ty.is_some() as usize..]; + let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..]; check_type_argument_count(tcx, span, num_provided, ty_param_defs); } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 3cb528eba63..5bfe58e78f1 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -13,7 +13,7 @@ use rustc::infer::{self, InferOk, TypeOrigin}; use rustc::ty; use rustc::traits::{self, Reveal}; use rustc::ty::error::ExpectedFound; -use rustc::ty::subst::{self, Subst, Substs}; +use rustc::ty::subst::{Subst, Substs}; use rustc::hir::map::Node; use rustc::hir::{ImplItemKind, TraitItem_}; @@ -95,8 +95,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } - let num_impl_m_type_params = impl_m.generics.types.len(subst::FnSpace); - let num_trait_m_type_params = trait_m.generics.types.len(subst::FnSpace); + let num_impl_m_type_params = impl_m.generics.types.len(); + let num_trait_m_type_params = trait_m.generics.types.len(); if num_impl_m_type_params != num_trait_m_type_params { span_err!(tcx.sess, impl_m_span, E0049, "method `{}` has {} type parameter{} \ @@ -389,8 +389,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, -> bool { - let trait_params = trait_generics.regions.get_slice(subst::FnSpace); - let impl_params = impl_generics.regions.get_slice(subst::FnSpace); + let trait_params = &trait_generics.regions[..]; + let impl_params = &impl_generics.regions[..]; debug!("check_region_bounds_on_impl_method: \ trait_generics={:?} \ diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index bfedb4fa6e1..b2af51c12e6 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -49,7 +49,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, variadic: false, }), })); - let i_n_tps = i_ty.generics.types.len(subst::FnSpace); + let i_n_tps = i_ty.generics.types.len(); if i_n_tps != n_tps { struct_span_err!(tcx.sess, it.span, E0094, "intrinsic has wrong number of type \ @@ -321,7 +321,7 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt, let tcx = ccx.tcx; let i_ty = tcx.lookup_item_type(tcx.map.local_def_id(it.id)); - let i_n_tps = i_ty.generics.types.len(subst::FnSpace); + let i_n_tps = i_ty.generics.types.len(); let name = it.name.as_str(); let (n_tps, inputs, output) = match &*name { diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index c071fce9896..8aa4ad56aea 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // variables. let num_supplied_types = supplied_method_types.len(); let method = pick.item.as_opt_method().unwrap(); - let num_method_types = method.generics.types.len(subst::FnSpace); + let num_method_types = method.generics.types.len(); if num_supplied_types > 0 && num_supplied_types != num_method_types { if num_method_types == 0 { diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index a9e08461fd2..b057ad3150b 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -183,15 +183,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let trait_def = self.tcx.lookup_trait_def(trait_def_id); if let Some(ref input_types) = opt_input_types { - assert_eq!(trait_def.generics.types.len(subst::TypeSpace) - 1, input_types.len()); + assert_eq!(trait_def.generics.types.len() - 1, input_types.len()); } - assert_eq!(trait_def.generics.types.len(subst::FnSpace), 0); assert!(trait_def.generics.regions.is_empty()); // Construct a trait-reference `self_ty : Trait` let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| { self.region_var_for_def(span, def) }, |def, substs| { + assert_eq!(def.space, subst::TypeSpace); if def.index == 0 { self_ty } else if let Some(ref input_types) = opt_input_types { @@ -221,8 +221,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; let method_item = self.trait_item(trait_def_id, m_name).unwrap(); let method_ty = method_item.as_opt_method().unwrap(); - assert_eq!(method_ty.generics.types.len(subst::FnSpace), 0); - assert_eq!(method_ty.generics.regions.len(subst::FnSpace), 0); + assert_eq!(method_ty.generics.types.len(), 0); + assert_eq!(method_ty.generics.regions.len(), 0); debug!("lookup_in_trait_adjusted: method_item={:?} method_ty={:?}", method_item, method_ty); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 044de179917..c52bb36911a 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -518,9 +518,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { trait_ref, trait_ref.substs, m); - assert_eq!(m.generics.types.len(subst::TypeSpace), + assert_eq!(m.generics.parent_types as usize, trait_ref.substs.types.len(subst::TypeSpace)); - assert_eq!(m.generics.regions.len(subst::TypeSpace), + assert_eq!(m.generics.parent_regions as usize, trait_ref.substs.regions.len(subst::TypeSpace)); } @@ -1232,8 +1232,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let xform_self_ty = method.fty.sig.input(0); let xform_self_ty = self.erase_late_bound_regions(&xform_self_ty); - if method.generics.types.is_empty_in(subst::FnSpace) && - method.generics.regions.is_empty_in(subst::FnSpace) { + if method.generics.types.is_empty() && method.generics.regions.is_empty() { xform_self_ty.subst(self.tcx, substs) } else { let substs = Substs::for_item(self.tcx, method.def_id, |def, _| { @@ -1260,17 +1259,13 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { impl_def_id: DefId) -> (Ty<'tcx>, &'tcx Substs<'tcx>) { - let impl_pty = self.tcx.lookup_item_type(impl_def_id); + let impl_ty = self.tcx.lookup_item_type(impl_def_id).ty; - let type_vars = - impl_pty.generics.types.map( - |_| self.next_ty_var()); + let substs = Substs::for_item(self.tcx, impl_def_id, + |_, _| ty::ReErased, + |_, _| self.next_ty_var()); - let region_placeholders = - impl_pty.generics.regions.map( - |_| ty::ReErased); // see erase_late_bound_regions() for an expl of why 'erased - - (impl_pty.ty, Substs::new(self.tcx, type_vars, region_placeholders)) + (impl_ty, substs) } /// Replace late-bound-regions bound by `value` with `'static` using diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ae3378f41f9..d699bafed9a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -881,8 +881,7 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // `{Self}` is allowed Position::ArgumentNamed(s) if s == "Self" => (), // So is `{A}` if A is a type parameter - Position::ArgumentNamed(s) => match types.as_full_slice() - .iter().find(|t| { + Position::ArgumentNamed(s) => match types.iter().find(|t| { t.name.as_str() == s }) { Some(_) => (), @@ -1693,7 +1692,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut ty = self.tcx.lookup_item_type(did).ty; if ty.is_fn() { // Tuple variants have fn type even in type namespace, extract true variant type from it - ty = self.tcx.no_late_bound_regions(&type_scheme.ty.fn_ret()).unwrap(); + ty = self.tcx.no_late_bound_regions(&ty.fn_ret()).unwrap(); } let type_predicates = self.tcx.lookup_predicates(did); let substs = AstConv::ast_path_substs_for_ty(self, self, @@ -3222,13 +3221,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.set_tainted_by_errors(); return None; } - Def::Variant(..) | Def::Struct(..) => { - Some(self.tcx.expect_variant_def(def)) + Def::Variant(type_did, _) | Def::Struct(type_did) => { + Some((type_did, self.tcx.expect_variant_def(def))) } - Def::TyAlias(did) | Def::AssociatedTy(_, did) => { + Def::TyAlias(did) => { if let Some(&ty::TyStruct(adt, _)) = self.tcx.opt_lookup_item_type(did) .map(|scheme| &scheme.ty.sty) { - Some(adt.struct_variant()) + Some((did, adt.struct_variant())) } else { None } @@ -3236,14 +3235,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => None }; - if let Some(variant) = variant { + if let Some((def_id, variant)) = variant { if variant.kind == ty::VariantKind::Tuple && !self.tcx.sess.features.borrow().relaxed_adts { emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic, "relaxed_adts", span, GateIssue::Language, "tuple structs and variants in struct patterns are unstable"); } - let ty = self.instantiate_type_path(def.def_id(), path, node_id); + let ty = self.instantiate_type_path(def_id, path, node_id); Some((variant, ty)) } else { struct_span_err!(self.tcx.sess, path.span, E0071, @@ -4122,25 +4121,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut fn_segment = None; match def { // Case 1 and 1b. Reference to a *type* or *enum variant*. - Def::SelfTy(..) | - Def::Struct(..) | - Def::Variant(..) | - Def::Enum(..) | - Def::TyAlias(..) | - Def::AssociatedTy(..) | - Def::Trait(..) | - Def::PrimTy(..) | - Def::TyParam(..) => { + Def::Struct(def_id) | + Def::Variant(_, def_id) | + Def::Enum(def_id) | + Def::TyAlias(def_id) | + Def::AssociatedTy(_, def_id) | + Def::Trait(def_id) => { // Everything but the final segment should have no // parameters at all. - type_segment = segments.last(); + let mut generics = self.tcx.lookup_generics(def_id); + if let Some(def_id) = generics.parent { + // Variant and struct constructors use the + // generics of their parent type definition. + generics = self.tcx.lookup_generics(def_id); + } + type_segment = Some((segments.last().unwrap(), generics)); } // Case 2. Reference to a top-level value. - Def::Fn(..) | - Def::Const(..) | - Def::Static(..) => { - fn_segment = segments.last(); + Def::Fn(def_id) | + Def::Const(def_id) | + Def::Static(def_id, _) => { + fn_segment = Some((segments.last().unwrap(), + self.tcx.lookup_generics(def_id))); } // Case 3. Reference to a method or associated const. @@ -4154,14 +4157,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::ImplContainer(_) => {} } + let generics = self.tcx.lookup_generics(def_id); if segments.len() >= 2 { - type_segment = Some(&segments[segments.len() - 2]); + let parent_generics = self.tcx.lookup_generics(generics.parent.unwrap()); + type_segment = Some((&segments[segments.len() - 2], parent_generics)); } else { // `::assoc` will end up here, and so can `T::assoc`. let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self"); ufcs_associated = Some((container, self_ty)); } - fn_segment = segments.last(); + fn_segment = Some((segments.last().unwrap(), generics)); } // Other cases. Various nonsense that really shouldn't show up @@ -4169,6 +4174,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // elsewhere. (I hope) Def::Mod(..) | Def::ForeignMod(..) | + Def::PrimTy(..) | + Def::SelfTy(..) | + Def::TyParam(..) | Def::Local(..) | Def::Label(..) | Def::Upvar(..) | @@ -4213,12 +4221,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // a problem. self.check_path_parameter_count(subst::TypeSpace, span, - scheme.generics, !require_type_space, &mut type_segment); self.check_path_parameter_count(subst::FnSpace, span, - scheme.generics, true, &mut fn_segment); @@ -4228,7 +4234,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { subst::TypeSpace => type_segment, subst::FnSpace => fn_segment }; - let lifetimes = match segment.map(|s| &s.parameters) { + let lifetimes = match segment.map(|(s, _)| &s.parameters) { Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..], Some(&hir::ParenthesizedParameters(_)) => bug!(), None => &[] @@ -4242,25 +4248,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }, |def, substs| { let mut i = def.index as usize; let segment = match def.space { - subst::TypeSpace => type_segment, + subst::TypeSpace => { + // Handle Self first, so we can adjust the index to match the AST. + match (type_segment, fn_segment) { + (Some((_, generics)), _) | (_, Some((_, generics))) => { + if generics.has_self { + if i == 0 { + return opt_self_ty.unwrap_or_else(|| { + self.type_var_for_def(span, def, substs) + }); + } + i -= 1; + } + } + _ => {} + } + type_segment + } subst::FnSpace => fn_segment }; - let types = match segment.map(|s| &s.parameters) { + let types = match segment.map(|(s, _)| &s.parameters) { Some(&hir::AngleBracketedParameters(ref data)) => &data.types[..], Some(&hir::ParenthesizedParameters(_)) => bug!(), None => &[] }; - // Handle Self first, so we can adjust the index to match the AST. - if scheme.generics.has_self && def.space == subst::TypeSpace { - if i == 0 { - return opt_self_ty.unwrap_or_else(|| { - self.type_var_for_def(span, def, substs) - }); - } - i -= 1; - } - let can_omit = def.space != subst::TypeSpace || !require_type_space; let default = if can_omit && types.len() == 0 { def.default @@ -4306,9 +4318,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // with the substituted impl type. let impl_scheme = self.tcx.lookup_item_type(impl_def_id); assert_eq!(substs.types.len(subst::TypeSpace), - impl_scheme.generics.types.len(subst::TypeSpace)); + impl_scheme.generics.types.len()); assert_eq!(substs.regions.len(subst::TypeSpace), - impl_scheme.generics.regions.len(subst::TypeSpace)); + impl_scheme.generics.regions.len()); let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty); match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) { @@ -4339,10 +4351,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn check_path_parameter_count(&self, space: subst::ParamSpace, span: Span, - generics: &ty::Generics<'tcx>, can_omit: bool, - segment: &mut Option<&hir::PathSegment>) { - let (lifetimes, types, bindings) = match segment.map(|s| &s.parameters) { + segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) { + let (lifetimes, types, bindings) = match segment.map(|(s, _)| &s.parameters) { Some(&hir::AngleBracketedParameters(ref data)) => { (&data.lifetimes[..], &data.types[..], &data.bindings[..]) } @@ -4357,7 +4368,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Check provided lifetime parameters. - let lifetime_defs = generics.regions.get_slice(space); + let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions); if lifetimes.len() > lifetime_defs.len() { let span = lifetimes[lifetime_defs.len()].span; span_err!(self.tcx.sess, span, E0088, @@ -4374,12 +4385,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Check provided type parameters. - let type_defs = generics.types.get_slice(space); - let type_defs = if space == subst::TypeSpace { - &type_defs[generics.has_self as usize..] - } else { - type_defs - }; + let type_defs = segment.map_or(&[][..], |(_, generics)| { + if space == subst::TypeSpace { + &generics.types[generics.has_self as usize..] + } else { + &generics.types + } + }); let required_len = type_defs.iter() .take_while(|d| d.default.is_none()) .count(); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index f2076895f08..f793ce7acb7 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -523,10 +523,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) { - let impl_params = generics.types.get_slice(subst::TypeSpace).iter() - .map(|tp| tp.name).collect::>(); + let parent = tcx.lookup_generics(generics.parent.unwrap()); + let impl_params: HashSet<_> = parent.types.iter().map(|tp| tp.name).collect(); - for method_param in generics.types.get_slice(subst::FnSpace) { + for method_param in &generics.types { if impl_params.contains(&method_param.name) { error_194(tcx, span, method_param.name); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8eef384f2cf..9e8fe710cc1 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem; use middle::const_val::ConstVal; use rustc_const_eval::EvalHint::UncheckedExprHint; use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err}; -use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace, VecPerParamSpace}; +use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace}; use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer}; use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme}; use rustc::ty::{VariantKind}; @@ -793,9 +793,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { } if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node { + let const_def_id = ccx.tcx.map.local_def_id(impl_item.id); + let ty_generics = generics_of_def_id(ccx, const_def_id); let ty = ccx.icx(&ty_predicates) .to_ty(&ExplicitRscope, &ty); - tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id), + tcx.register_item_type(const_def_id, TypeScheme { generics: ty_generics, ty: ty, @@ -858,11 +860,13 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { // Convert all the associated constants. for trait_item in trait_items { if let hir::ConstTraitItem(ref ty, ref default) = trait_item.node { + let const_def_id = ccx.tcx.map.local_def_id(trait_item.id); + let ty_generics = generics_of_def_id(ccx, const_def_id); let ty = ccx.icx(&trait_predicates) .to_ty(&ExplicitRscope, ty); - tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id), + tcx.register_item_type(const_def_id, TypeScheme { - generics: trait_def.generics, + generics: ty_generics, ty: ty, }); convert_associated_const(ccx, @@ -957,7 +961,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, predicates: ty::GenericPredicates<'tcx>) { let tcx = ccx.tcx; let def_id = tcx.map.local_def_id(ctor_id); - tcx.generics.borrow_mut().insert(def_id, scheme.generics); + generics_of_def_id(ccx, def_id); let ctor_ty = match variant.kind { VariantKind::Unit | VariantKind::Struct => scheme.ty, VariantKind::Tuple => { @@ -1389,24 +1393,35 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, use rustc::hir::map::*; use rustc::hir::*; + let node = tcx.map.get(node_id); + let parent_def_id = match node { + NodeImplItem(_) | + NodeTraitItem(_) | + NodeVariant(_) | + NodeStructCtor(_) => { + let parent_id = tcx.map.get_parent(node_id); + Some(tcx.map.local_def_id(parent_id)) + } + _ => None + }; + let mut opt_self = None; - let mut base_def_id = None; let mut allow_defaults = false; let no_generics = hir::Generics::empty(); - let (space, ast_generics) = match tcx.map.get(node_id) { - NodeImplItem(&ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) | - NodeTraitItem(&TraitItem { node: MethodTraitItem(ref sig, _), .. }) => { - let parent_id = tcx.map.get_parent(node_id); - base_def_id = Some(tcx.map.local_def_id(parent_id)); - (FnSpace, &sig.generics) + let (space, ast_generics) = match node { + NodeTraitItem(item) => { + match item.node { + MethodTraitItem(ref sig, _) => (FnSpace, &sig.generics), + _ => (FnSpace, &no_generics) + } } - NodeImplItem(_) | - NodeTraitItem(_) => { - let parent_id = tcx.map.get_parent(node_id); - base_def_id = Some(tcx.map.local_def_id(parent_id)); - (FnSpace, &no_generics) + NodeImplItem(item) => { + match item.node { + ImplItemKind::Method(ref sig, _) => (FnSpace, &sig.generics), + _ => (FnSpace, &no_generics) + } } NodeItem(item) => { @@ -1457,9 +1472,16 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, _ => (TypeSpace, &no_generics) }; - let empty_generics = ty::Generics::empty(); - let base_generics = base_def_id.map_or(&empty_generics, |def_id| { - generics_of_def_id(ccx, def_id) + let has_self = opt_self.is_some(); + let mut parent_has_self = false; + let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| { + let generics = generics_of_def_id(ccx, def_id); + assert_eq!(generics.parent, None); + assert_eq!(generics.parent_regions, 0); + assert_eq!(generics.parent_types, 0); + assert_eq!(has_self, false); + parent_has_self = generics.has_self; + (generics.regions.len(), generics.types.len()) }); let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics); @@ -1477,32 +1499,15 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // Now create the real type parameters. let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| { - let i = opt_self.is_some() as u32 + i as u32; + let i = has_self as u32 + i as u32; get_or_create_type_parameter_def(ccx, ast_generics, space, i, p, allow_defaults) - }).collect(); - - let has_self = base_generics.has_self || opt_self.is_some(); - let (regions, types) = match space { - TypeSpace => { - assert_eq!(base_generics.regions.as_full_slice().len(), 0); - assert_eq!(base_generics.types.as_full_slice().len(), 0); - (VecPerParamSpace::new(regions, vec![]), - VecPerParamSpace::new(opt_self.into_iter().chain(types).collect(), vec![])) - } - FnSpace => { - assert_eq!(base_generics.regions.len(FnSpace), 0); - assert_eq!(base_generics.types.len(FnSpace), 0); - (VecPerParamSpace::new(base_generics.regions.get_slice(TypeSpace).to_vec(), - regions), - VecPerParamSpace::new(base_generics.types.get_slice(TypeSpace).to_vec(), - types)) - } - }; + }); + let types: Vec<_> = opt_self.into_iter().chain(types).collect(); // Debugging aid. if tcx.has_attr(def_id, "rustc_object_lifetime_default") { let object_lifetime_default_reprs: String = - types.as_full_slice().iter().map(|t| { + types.iter().map(|t| { match t.object_lifetime_default { ty::ObjectLifetimeDefault::Specific(r) => r.to_string(), d => format!("{:?}", d), @@ -1512,9 +1517,12 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } tcx.alloc_generics(ty::Generics { + parent: parent_def_id, + parent_regions: parent_regions as u32, + parent_types: parent_types as u32, regions: regions, types: types, - has_self: has_self + has_self: has_self || parent_has_self }) }) } @@ -2148,7 +2156,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, &mut input_parameters); let ty_generics = generics_of_def_id(ccx, impl_def_id); - for (ty_param, param) in ty_generics.types.as_full_slice().iter().zip(&generics.ty_params) { + for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) { let param_ty = ty::ParamTy::for_def(ty_param); if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) { report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string()); diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 2b88689ff12..95ddb59c0e2 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -301,8 +301,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_substs( generics, trait_ref.def_id, - trait_def.generics.types.as_full_slice(), - trait_def.generics.regions.as_full_slice(), + &trait_def.generics.types, + &trait_def.generics.regions, trait_ref.substs, variance); } @@ -359,16 +359,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // README.md for a discussion on dep-graph management. self.tcx().dep_graph.read(ItemVariances::to_dep_node(&def.did)); - // All type parameters on enums and structs should be - // in the TypeSpace. - assert!(item_type.generics.types.is_empty_in(subst::FnSpace)); - assert!(item_type.generics.regions.is_empty_in(subst::FnSpace)); - self.add_constraints_from_substs( generics, def.did, - item_type.generics.types.as_full_slice(), - item_type.generics.regions.as_full_slice(), + &item_type.generics.types, + &item_type.generics.regions, substs, variance); } @@ -385,8 +380,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_substs( generics, trait_ref.def_id, - trait_def.generics.types.as_full_slice(), - trait_def.generics.regions.as_full_slice(), + &trait_def.generics.types, + &trait_def.generics.regions, trait_ref.substs, variance); } @@ -406,7 +401,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::TyParam(ref data) => { - let def_id = generics.types.get(data.space, data.idx as usize).def_id; + assert_eq!(data.space, subst::TypeSpace); + assert_eq!(generics.parent, None); + let def_id = generics.types[data.idx as usize].def_id; let node_id = self.tcx().map.as_local_node_id(def_id).unwrap(); match self.terms_cx.inferred_map.get(&node_id) { Some(&index) => { @@ -493,8 +490,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { variance: VarianceTermPtr<'a>) { match region { ty::ReEarlyBound(ref data) => { - let def_id = - generics.regions.get(data.space, data.index as usize).def_id; + assert_eq!(data.space, subst::TypeSpace); + assert_eq!(generics.parent, None); + let def_id = generics.regions[data.index as usize].def_id; let node_id = self.tcx().map.as_local_node_id(def_id).unwrap(); if self.is_to_be_inferred(node_id) { let index = self.inferred_index(node_id); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index b4be201440c..427468069d0 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -21,7 +21,6 @@ use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::hir::print as pprust; use rustc::ty::{self, TyCtxt}; -use rustc::ty::subst; use rustc_const_eval::lookup_const_by_id; @@ -161,7 +160,7 @@ pub fn build_external_trait<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tc let def = tcx.lookup_trait_def(did); let trait_items = tcx.trait_items(did).clean(cx); let predicates = tcx.lookup_predicates(did); - let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx); + let generics = (def.generics, &predicates).clean(cx); let generics = filter_non_trait_generics(did, generics); let (generics, supertrait_bounds) = separate_supertrait_bounds(generics); clean::Trait { @@ -189,7 +188,7 @@ fn build_external_function<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx let predicates = tcx.lookup_predicates(did); clean::Function { decl: decl, - generics: (t.generics, &predicates, subst::FnSpace).clean(cx), + generics: (t.generics, &predicates).clean(cx), unsafety: style, constness: constness, abi: abi, @@ -209,7 +208,7 @@ fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, &[..] if variant.kind == ty::VariantKind::Tuple => doctree::Tuple, _ => doctree::Plain, }, - generics: (t.generics, &predicates, subst::TypeSpace).clean(cx), + generics: (t.generics, &predicates).clean(cx), fields: variant.fields.clean(cx), fields_stripped: false, } @@ -222,7 +221,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, match t.ty.sty { ty::TyEnum(edef, _) if !tcx.sess.cstore.is_typedef(did) => { return clean::EnumItem(clean::Enum { - generics: (t.generics, &predicates, subst::TypeSpace).clean(cx), + generics: (t.generics, &predicates).clean(cx), variants_stripped: false, variants: edef.variants.clean(cx), }) @@ -232,7 +231,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, clean::TypedefItem(clean::Typedef { type_: t.ty.clean(cx), - generics: (t.generics, &predicates, subst::TypeSpace).clean(cx), + generics: (t.generics, &predicates).clean(cx), }, false) } @@ -393,9 +392,11 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, // because an associated type won't have generics on the LHS let typedef = clean::Typedef { type_: assoc_ty.ty.unwrap().clean(cx), - generics: (&ty::Generics::empty(), - &ty::GenericPredicates::empty(), - subst::TypeSpace).clean(cx) + generics: clean::Generics { + lifetimes: vec![], + type_params: vec![], + where_predicates: vec![] + } }; Some(clean::Item { name: Some(assoc_ty.name.clean(cx)), @@ -434,7 +435,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, provided_trait_methods: provided, trait_: trait_, for_: for_, - generics: (ty.generics, &predicates, subst::TypeSpace).clean(cx), + generics: (ty.generics, &predicates).clean(cx), items: trait_items, polarity: polarity.map(|p| { p.clean(cx) }), }), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6fae7ddc24a..07821a730cc 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -973,17 +973,16 @@ impl Clean for hir::Generics { } impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, - &'a ty::GenericPredicates<'tcx>, - subst::ParamSpace) { + &'a ty::GenericPredicates<'tcx>) { fn clean(&self, cx: &DocContext) -> Generics { use self::WherePredicate as WP; - let (gens, preds, space) = *self; + let (gens, preds) = *self; // Bounds in the type_params and lifetimes fields are repeated in the // predicates field (see rustc_typeck::collect::ty_generics), so remove // them. - let stripped_typarams = gens.types.get_slice(space).iter().filter_map(|tp| { + let stripped_typarams = gens.types.iter().filter_map(|tp| { if tp.name == keywords::SelfType.name() { assert_eq!(tp.index, 0); None @@ -991,7 +990,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, Some(tp.clean(cx)) } }).collect::>(); - let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| { + let stripped_lifetimes = gens.regions.iter().map(|rp| { let mut srp = rp.clone(); srp.bounds = Vec::new(); srp.clean(cx) @@ -1359,8 +1358,7 @@ impl<'tcx> Clean for ty::Method<'tcx> { predicates: self.predicates.predicates[method_start..].to_vec() }; - let generics = (self.generics, &method_predicates, - subst::FnSpace).clean(cx); + let generics = (self.generics, &method_predicates).clean(cx); let mut decl = (self.def_id, &self.fty.sig).clean(cx); match self.explicit_self { ty::ExplicitSelfCategory::ByValue => { @@ -2929,7 +2927,7 @@ impl<'tcx> Clean for ty::AssociatedType<'tcx> { // applied to this associated type in question. let def = cx.tcx().lookup_trait_def(did); let predicates = cx.tcx().lookup_predicates(did); - let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx); + let generics = (def.generics, &predicates).clean(cx); generics.where_predicates.iter().filter_map(|pred| { let (name, self_type, trait_, bounds) = match *pred { WherePredicate::BoundPredicate {