From 7b45a892a482f70ccb696abdcab089cce5f2d612 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 18 Apr 2018 11:33:52 +0100 Subject: [PATCH] Use GenericParamCount instead of FxHashMap --- src/librustc/hir/lowering.rs | 3 +- src/librustc/traits/object_safety.rs | 4 +- src/librustc/ty/mod.rs | 39 +++++++++----------- src/librustc/util/ppaux.rs | 22 +++++------ src/librustc_mir/monomorphize/collector.rs | 2 +- src/librustc_mir/transform/check_unsafety.rs | 4 +- src/librustc_trans/debuginfo/mod.rs | 8 +++- src/librustc_typeck/astconv.rs | 6 +-- src/librustc_typeck/check/compare_method.rs | 10 ++--- src/librustc_typeck/check/intrinsic.rs | 6 +-- src/librustc_typeck/check/method/confirm.rs | 4 +- src/librustc_typeck/check/mod.rs | 27 ++++---------- src/librustdoc/clean/mod.rs | 37 ++++++++++--------- 13 files changed, 82 insertions(+), 90 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index c780d1b72f2a..77c2dd219c47 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -46,7 +46,6 @@ use hir::HirVec; use hir::map::{DefKey, DefPathData, Definitions}; use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX}; use hir::def::{Def, PathResolution}; -use ty::Kind; use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES}; use middle::cstore::CrateStore; use rustc_data_structures::indexed_vec::IndexVec; @@ -1462,7 +1461,7 @@ impl<'a> LoweringContext<'a> { assert!(!def_id.is_local()); let item_generics = self.cstore.item_generics_cloned_untracked(def_id, self.sess); - let n = item_generics.param_counts()[&Kind::Lifetime]; + let n = item_generics.param_counts().lifetimes; self.type_def_lifetime_params.insert(def_id, n); n }); diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index cb8ff674188c..d659d235cd13 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -21,7 +21,7 @@ use super::elaborate_predicates; use hir::def_id::DefId; use traits; -use ty::{self, Ty, TyCtxt, Kind, TypeFoldable}; +use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::subst::Substs; use ty::util::ExplicitSelf; use std::borrow::Cow; @@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } // We can't monomorphize things like `fn foo(...)`. - if self.generics_of(method.def_id).param_counts()[&Kind::Type] != 0 { + if self.generics_of(method.def_id).param_counts().types != 0 { return Some(MethodViolationCode::Generic); } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 034107852626..0cbee56487ff 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -757,18 +757,6 @@ impl ty::EarlyBoundRegion { } } -#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug, RustcEncodable, RustcDecodable)] -pub enum Kind { - Lifetime, - Type, -} - -impl Kind { - pub fn iter<'a>() -> impl Iterator { - [Kind::Lifetime, Kind::Type].into_iter() - } -} - #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub enum GenericParamDef { Lifetime(RegionParamDef), @@ -791,6 +779,11 @@ impl GenericParamDef { } } +pub struct GenericParamCount { + pub lifetimes: usize, + pub types: usize, +} + /// Information about the formal type/lifetime parameters associated /// with an item or method. Analogous to hir::Generics. /// @@ -814,18 +807,20 @@ impl<'a, 'gcx, 'tcx> Generics { self.parent_count + self.params.len() } - pub fn param_counts(&self) -> FxHashMap { - let mut param_counts: FxHashMap<_, _> = FxHashMap(); - Kind::iter().for_each(|kind| { - param_counts.insert(*kind, 0); - }); + pub fn param_counts(&self) -> GenericParamCount { + // We could cache this as a property of `GenericParamCount`, but + // the aim is to refactor this away entirely eventually and the + // presence of this method will be a constant reminder. + let mut param_counts = GenericParamCount { + lifetimes: 0, + types: 0, + }; for param in self.params.iter() { - let key = match param { - GenericParamDef::Type(_) => Kind::Type, - GenericParamDef::Lifetime(_) => Kind::Lifetime, + match param { + GenericParamDef::Lifetime(_) => param_counts.lifetimes += 1, + GenericParamDef::Type(_) => param_counts.types += 1, }; - *param_counts.get_mut(&key).unwrap() += 1; } param_counts @@ -904,7 +899,7 @@ impl<'a, 'gcx, 'tcx> Generics { // And it can be seen that in both cases, to move from a substs // offset to a generics offset you just have to offset by the // number of regions. - let type_param_offset = self.param_counts()[&Kind::Lifetime]; + let type_param_offset = self.param_counts().lifetimes; let has_self = self.has_self && self.parent.is_none(); let is_separated_self = type_param_offset != 0 && index == 0 && has_self; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0817ededfaac..ba8694602526 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -19,8 +19,8 @@ use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon}; use ty::{TyDynamic, TyInt, TyUint, TyInfer}; -use ty::{self, Ty, TyCtxt, TypeFoldable, Kind}; -use util::nodemap::{FxHashSet, FxHashMap}; +use ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount}; +use util::nodemap::FxHashSet; use std::cell::Cell; use std::fmt; @@ -257,10 +257,10 @@ impl PrintContext { let verbose = self.is_verbose; let mut num_supplied_defaults = 0; let mut has_self = false; - let mut param_counts = FxHashMap(); - Kind::iter().for_each(|kind| { - param_counts.insert(*kind, 0); - }); + let mut param_counts = GenericParamCount { + lifetimes: 0, + types: 0, + }; let mut is_value_path = false; let fn_trait_kind = ty::tls::with(|tcx| { // Unfortunately, some kinds of items (e.g., closures) don't have @@ -314,7 +314,7 @@ impl PrintContext { if let Some(def_id) = generics.parent { // Methods. assert!(is_value_path); - child_types = child_param_counts[&Kind::Type]; + child_types = child_param_counts.types; generics = tcx.generics_of(def_id); param_counts = generics.param_counts(); @@ -407,10 +407,10 @@ impl PrintContext { Ok(()) }; - print_regions(f, "<", 0, param_counts[&Kind::Lifetime])?; + print_regions(f, "<", 0, param_counts.lifetimes)?; let tps = substs.types() - .take(param_counts[&Kind::Type] - num_supplied_defaults) + .take(param_counts.types - num_supplied_defaults) .skip(has_self as usize); for ty in tps { @@ -442,10 +442,10 @@ impl PrintContext { write!(f, "::{}", item_name)?; } - print_regions(f, "::<", param_counts[&Kind::Lifetime], usize::MAX)?; + print_regions(f, "::<", param_counts.lifetimes, usize::MAX)?; // FIXME: consider being smart with defaults here too - for ty in substs.types().skip(param_counts[&Kind::Type]) { + for ty in substs.types().skip(param_counts.types) { start_or_continue(f, "::<", ", ")?; ty.print_display(f, self)?; } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 99a7e0abe167..92b4babe8a3b 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1108,7 +1108,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, continue; } - if tcx.generics_of(method.def_id).param_counts()[&ty::Kind::Type] != 0 { + if tcx.generics_of(method.def_id).param_counts().types != 0 { continue; } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 58e63fe6b048..b65353e449f6 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -13,7 +13,7 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::Lrc; use rustc::ty::maps::Providers; -use rustc::ty::{self, TyCtxt, Kind}; +use rustc::ty::{self, TyCtxt}; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE}; @@ -357,7 +357,7 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D // FIXME: when we make this a hard error, this should have its // own error code. - let message = if tcx.generics_of(def_id).param_counts()[&Kind::Type] != 0 { + let message = if tcx.generics_of(def_id).param_counts().types != 0 { format!("#[derive] can't be used on a #[repr(packed)] struct with \ type parameters (error E0133)") } else { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 2463e571436e..0990c1f1714c 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -26,7 +26,7 @@ use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArr use rustc::hir::TransFnAttrFlags; use rustc::hir::def_id::{DefId, CrateNum}; use rustc::ty::subst::Substs; -use rustc::ty::{Kind, GenericParamDef}; +use rustc::ty::GenericParamDef; use abi::Abi; use common::CodegenCx; @@ -197,6 +197,12 @@ pub fn finalize(cx: &CodegenCx) { }; } +#[derive(PartialEq, Eq, Hash)] +pub enum Kind { + Lifetime, + Type, +} + /// Creates the function-specific debug context. /// /// Returns the FunctionDebugContext for the function which holds state needed diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d77a090de682..11003a49316e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -210,7 +210,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let decl_generics = tcx.generics_of(def_id); let param_counts = decl_generics.param_counts(); let num_types_provided = parameters.types.len(); - let expected_num_region_params = param_counts[&ty::Kind::Lifetime]; + let expected_num_region_params = param_counts.lifetimes; let supplied_num_region_params = parameters.lifetimes.len(); if expected_num_region_params != supplied_num_region_params { report_lifetime_number_error(tcx, span, @@ -223,7 +223,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // Check the number of type parameters supplied by the user. let type_params_offset = self_ty.is_some() as usize; - let ty_param_defs = param_counts[&ty::Kind::Type] - type_params_offset; + let ty_param_defs = param_counts.types - type_params_offset; if !infer_types || num_types_provided > ty_param_defs { check_type_argument_count(tcx, span, @@ -260,7 +260,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { return ty; } - let i = i - (param_counts[&ty::Kind::Lifetime] + type_params_offset); + let i = i - (param_counts.lifetimes + type_params_offset); if i < num_types_provided { // A provided type parameter. self.ast_ty_to_ty(¶meters.types[i]) diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index e02ba7640574..c2c250249ad8 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -10,7 +10,7 @@ use rustc::hir::{self, ImplItemKind, TraitItemKind}; use rustc::infer::{self, InferOk}; -use rustc::ty::{self, TyCtxt, Kind}; +use rustc::ty::{self, TyCtxt}; use rustc::ty::util::ExplicitSelf; use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; use rustc::ty::error::{ExpectedFound, TypeError}; @@ -357,8 +357,8 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_to_skol_substs: &Substs<'tcx>) -> Result<(), ErrorReported> { let span = tcx.sess.codemap().def_span(span); - let trait_params = trait_generics.param_counts()[&Kind::Lifetime]; - let impl_params = impl_generics.param_counts()[&Kind::Lifetime]; + let trait_params = trait_generics.param_counts().lifetimes; + let impl_params = impl_generics.param_counts().lifetimes; debug!("check_region_bounds_on_impl_method: \ trait_generics={:?} \ @@ -574,8 +574,8 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Result<(), ErrorReported> { let impl_m_generics = tcx.generics_of(impl_m.def_id); let trait_m_generics = tcx.generics_of(trait_m.def_id); - let num_impl_m_type_params = impl_m_generics.param_counts()[&Kind::Type]; - let num_trait_m_type_params = trait_m_generics.param_counts()[&Kind::Type]; + let num_impl_m_type_params = impl_m_generics.param_counts().types; + let num_trait_m_type_params = trait_m_generics.param_counts().types; if num_impl_m_type_params != num_trait_m_type_params { let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index e3d7e16e15c9..1817b4aba191 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -13,7 +13,7 @@ use intrinsics; use rustc::traits::{ObligationCause, ObligationCauseCode}; -use rustc::ty::{self, TyCtxt, Ty, Kind}; +use rustc::ty::{self, TyCtxt, Ty}; use rustc::util::nodemap::FxHashMap; use require_same_types; @@ -45,7 +45,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - let i_n_tps = tcx.generics_of(def_id).param_counts()[&Kind::Type]; + let i_n_tps = tcx.generics_of(def_id).param_counts().types; if i_n_tps != n_tps { let span = match it.node { hir::ForeignItemFn(_, _, ref generics) => generics.span, @@ -346,7 +346,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; let def_id = tcx.hir.local_def_id(it.id); - let i_n_tps = tcx.generics_of(def_id).param_counts()[&Kind::Type]; + let i_n_tps = tcx.generics_of(def_id).param_counts().types; 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 038927bbac64..eab26046147b 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -15,7 +15,7 @@ use check::{FnCtxt, PlaceOp, callee, Needs}; use hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::traits; -use rustc::ty::{self, Ty, Kind}; +use rustc::ty::{self, Ty}; use rustc::ty::subst::Subst; use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref}; use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; @@ -333,7 +333,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { } else if let Some(ast_ty) = provided.as_ref().and_then(|p| { let idx = - i - parent_substs.len() - method_generics.param_counts()[&Kind::Lifetime]; + i - parent_substs.len() - method_generics.param_counts().lifetimes; p.types.get(idx) }) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ad1e5ad79923..3df584040ad3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1239,8 +1239,7 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item } else { for item in &m.items { let generics = tcx.generics_of(tcx.hir.local_def_id(item.id)); - let param_counts = generics.param_counts(); - if generics.params.len() - param_counts[&ty::Kind::Lifetime] != 0 { + if generics.params.len() - generics.param_counts().lifetimes != 0 { let mut err = struct_span_err!(tcx.sess, item.span, E0044, "foreign items may not have type parameters"); err.span_label(item.span, "can't have type parameters"); @@ -4800,7 +4799,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Skip over the lifetimes in the same segment. if let Some((_, generics)) = segment { - i -= generics.param_counts()[&ty::Kind::Lifetime]; + i -= generics.param_counts().lifetimes; } if let Some(ast_ty) = types.get(i) { @@ -4921,15 +4920,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Check provided parameters. let (ty_non_def_req_len, ty_req_len, lt_req_len) = segment.map_or((0, 0, 0), |(_, generics)| { - let params_count = generics.param_counts(); + let param_counts = generics.param_counts(); let type_params_offset = (generics.parent.is_none() && generics.has_self) as usize; - let type_params = params_count[&ty::Kind::Type] - type_params_offset; + let type_params = param_counts.types - type_params_offset; let type_params_barring_defaults = generics.type_params_without_defaults() - type_params_offset; - (type_params_barring_defaults, type_params, params_count[&ty::Kind::Lifetime]) + (type_params_barring_defaults, type_params, param_counts.lifetimes) }); if types.len() > ty_req_len { @@ -5088,22 +5087,12 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if generics.ty_params().next().is_none() { return; } let mut tps_used = vec![false; generics.ty_params().count()]; - let mut param_counts = FxHashMap(); - param_counts.insert(ty::Kind::Type, 0); - param_counts.insert(ty::Kind::Lifetime, 0); - - for param in generics.params.iter() { - let key = match param { - hir::GenericParam::Type(_) => ty::Kind::Type, - hir::GenericParam::Lifetime(_) => ty::Kind::Lifetime, - }; - *param_counts.get_mut(&key).unwrap() += 1; - } + let lifetime_count = generics.lifetimes().count(); for leaf_ty in ty.walk() { - if let ty::TyParam(ty::ParamTy {idx, .. }) = leaf_ty.sty { + if let ty::TyParam(ty::ParamTy {idx, ..}) = leaf_ty.sty { debug!("Found use of ty param num {}", idx); - tps_used[idx as usize - param_counts[&ty::Kind::Lifetime]] = true; + tps_used[idx as usize - lifetime_count] = true; } else if let ty::TyError = leaf_ty.sty { // If there already another error, do not emit an error for not using a type Parameter assert!(tcx.sess.err_count() > 0); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 667d7f1e1605..5146a29d4e37 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -41,7 +41,7 @@ use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::hir::def_id::DefIndexAddressSpace; use rustc::ty::subst::Substs; -use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind, Kind}; +use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind, GenericParamCount}; use rustc::middle::stability; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_typeck::hir_ty_to_ty; @@ -2684,31 +2684,34 @@ impl Clean for hir::Ty { let mut ty_substs = FxHashMap(); let mut lt_substs = FxHashMap(); provided_params.with_parameters(|provided_params| { - let mut indices = FxHashMap(); + let mut indices = GenericParamCount { + lifetimes: 0, + types: 0 + }; for param in generics.params.iter() { match param { - hir::GenericParam::Type(ty_param) => { - let i = indices.entry(Kind::Type).or_insert(0); - let ty_param_def = - Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id)); - if let Some(ty) = provided_params.types.get(*i).cloned() { - ty_substs.insert(ty_param_def, ty.into_inner().clean(cx)); - } else if let Some(default) = ty_param.default.clone() { - ty_substs.insert(ty_param_def, - default.into_inner().clean(cx)); - } - *i += 1; - } hir::GenericParam::Lifetime(lt_param) => { - let i = indices.entry(Kind::Type).or_insert(0); - if let Some(lt) = provided_params.lifetimes.get(*i).cloned() { + if let Some(lt) = provided_params.lifetimes + .get(indices.lifetimes).cloned() { if !lt.is_elided() { let lt_def_id = cx.tcx.hir.local_def_id(lt_param.lifetime.id); lt_substs.insert(lt_def_id, lt.clean(cx)); } } - *i += 1; + indices.lifetimes += 1; + } + hir::GenericParam::Type(ty_param) => { + let ty_param_def = + Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id)); + if let Some(ty) = provided_params.types + .get(indices.types).cloned() { + ty_substs.insert(ty_param_def, ty.into_inner().clean(cx)); + } else if let Some(default) = ty_param.default.clone() { + ty_substs.insert(ty_param_def, + default.into_inner().clean(cx)); + } + indices.types += 1; } } }