提交 7b45a892 编写于 作者: V varkor

Use GenericParamCount instead of FxHashMap

上级 a17896a3
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
use hir::map::{DefKey, DefPathData, Definitions}; use hir::map::{DefKey, DefPathData, Definitions};
use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX}; use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
use hir::def::{Def, PathResolution}; use hir::def::{Def, PathResolution};
use ty::Kind;
use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES}; use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
use middle::cstore::CrateStore; use middle::cstore::CrateStore;
use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::indexed_vec::IndexVec;
...@@ -1462,7 +1461,7 @@ fn lower_qpath( ...@@ -1462,7 +1461,7 @@ fn lower_qpath(
assert!(!def_id.is_local()); assert!(!def_id.is_local());
let item_generics = let item_generics =
self.cstore.item_generics_cloned_untracked(def_id, self.sess); 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); self.type_def_lifetime_params.insert(def_id, n);
n n
}); });
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
use hir::def_id::DefId; use hir::def_id::DefId;
use traits; use traits;
use ty::{self, Ty, TyCtxt, Kind, TypeFoldable}; use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::subst::Substs; use ty::subst::Substs;
use ty::util::ExplicitSelf; use ty::util::ExplicitSelf;
use std::borrow::Cow; use std::borrow::Cow;
...@@ -284,7 +284,7 @@ fn virtual_call_violation_for_method(self, ...@@ -284,7 +284,7 @@ fn virtual_call_violation_for_method(self,
} }
// We can't monomorphize things like `fn foo<A>(...)`. // We can't monomorphize things like `fn foo<A>(...)`.
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); return Some(MethodViolationCode::Generic);
} }
......
...@@ -757,18 +757,6 @@ pub fn to_bound_region(&self) -> ty::BoundRegion { ...@@ -757,18 +757,6 @@ pub fn to_bound_region(&self) -> ty::BoundRegion {
} }
} }
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum Kind {
Lifetime,
Type,
}
impl Kind {
pub fn iter<'a>() -> impl Iterator<Item = &'a Kind> {
[Kind::Lifetime, Kind::Type].into_iter()
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum GenericParamDef { pub enum GenericParamDef {
Lifetime(RegionParamDef), Lifetime(RegionParamDef),
...@@ -791,6 +779,11 @@ pub fn get_type(&self) -> Option<TypeParamDef> { ...@@ -791,6 +779,11 @@ pub fn get_type(&self) -> Option<TypeParamDef> {
} }
} }
pub struct GenericParamCount {
pub lifetimes: usize,
pub types: usize,
}
/// Information about the formal type/lifetime parameters associated /// Information about the formal type/lifetime parameters associated
/// with an item or method. Analogous to hir::Generics. /// with an item or method. Analogous to hir::Generics.
/// ///
...@@ -814,18 +807,20 @@ pub fn count(&self) -> usize { ...@@ -814,18 +807,20 @@ pub fn count(&self) -> usize {
self.parent_count + self.params.len() self.parent_count + self.params.len()
} }
pub fn param_counts(&self) -> FxHashMap<Kind, usize> { pub fn param_counts(&self) -> GenericParamCount {
let mut param_counts: FxHashMap<_, _> = FxHashMap(); // We could cache this as a property of `GenericParamCount`, but
Kind::iter().for_each(|kind| { // the aim is to refactor this away entirely eventually and the
param_counts.insert(*kind, 0); // presence of this method will be a constant reminder.
}); let mut param_counts = GenericParamCount {
lifetimes: 0,
types: 0,
};
for param in self.params.iter() { for param in self.params.iter() {
let key = match param { match param {
GenericParamDef::Type(_) => Kind::Type, GenericParamDef::Lifetime(_) => param_counts.lifetimes += 1,
GenericParamDef::Lifetime(_) => Kind::Lifetime, GenericParamDef::Type(_) => param_counts.types += 1,
}; };
*param_counts.get_mut(&key).unwrap() += 1;
} }
param_counts param_counts
...@@ -904,7 +899,7 @@ pub fn type_param(&'tcx self, ...@@ -904,7 +899,7 @@ pub fn type_param(&'tcx self,
// And it can be seen that in both cases, to move from a substs // 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 // offset to a generics offset you just have to offset by the
// number of regions. // 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 has_self = self.has_self && self.parent.is_none();
let is_separated_self = type_param_offset != 0 && index == 0 && has_self; let is_separated_self = type_param_offset != 0 && index == 0 && has_self;
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon}; use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon};
use ty::{TyDynamic, TyInt, TyUint, TyInfer}; use ty::{TyDynamic, TyInt, TyUint, TyInfer};
use ty::{self, Ty, TyCtxt, TypeFoldable, Kind}; use ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount};
use util::nodemap::{FxHashSet, FxHashMap}; use util::nodemap::FxHashSet;
use std::cell::Cell; use std::cell::Cell;
use std::fmt; use std::fmt;
...@@ -257,10 +257,10 @@ fn parameterized<F: fmt::Write>(&mut self, ...@@ -257,10 +257,10 @@ fn parameterized<F: fmt::Write>(&mut self,
let verbose = self.is_verbose; let verbose = self.is_verbose;
let mut num_supplied_defaults = 0; let mut num_supplied_defaults = 0;
let mut has_self = false; let mut has_self = false;
let mut param_counts = FxHashMap(); let mut param_counts = GenericParamCount {
Kind::iter().for_each(|kind| { lifetimes: 0,
param_counts.insert(*kind, 0); types: 0,
}); };
let mut is_value_path = false; let mut is_value_path = false;
let fn_trait_kind = ty::tls::with(|tcx| { let fn_trait_kind = ty::tls::with(|tcx| {
// Unfortunately, some kinds of items (e.g., closures) don't have // Unfortunately, some kinds of items (e.g., closures) don't have
...@@ -314,7 +314,7 @@ fn parameterized<F: fmt::Write>(&mut self, ...@@ -314,7 +314,7 @@ fn parameterized<F: fmt::Write>(&mut self,
if let Some(def_id) = generics.parent { if let Some(def_id) = generics.parent {
// Methods. // Methods.
assert!(is_value_path); assert!(is_value_path);
child_types = child_param_counts[&Kind::Type]; child_types = child_param_counts.types;
generics = tcx.generics_of(def_id); generics = tcx.generics_of(def_id);
param_counts = generics.param_counts(); param_counts = generics.param_counts();
...@@ -407,10 +407,10 @@ fn parameterized<F: fmt::Write>(&mut self, ...@@ -407,10 +407,10 @@ fn parameterized<F: fmt::Write>(&mut self,
Ok(()) Ok(())
}; };
print_regions(f, "<", 0, param_counts[&Kind::Lifetime])?; print_regions(f, "<", 0, param_counts.lifetimes)?;
let tps = substs.types() let tps = substs.types()
.take(param_counts[&Kind::Type] - num_supplied_defaults) .take(param_counts.types - num_supplied_defaults)
.skip(has_self as usize); .skip(has_self as usize);
for ty in tps { for ty in tps {
...@@ -442,10 +442,10 @@ fn parameterized<F: fmt::Write>(&mut self, ...@@ -442,10 +442,10 @@ fn parameterized<F: fmt::Write>(&mut self,
write!(f, "::{}", item_name)?; 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 // 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, "::<", ", ")?; start_or_continue(f, "::<", ", ")?;
ty.print_display(f, self)?; ty.print_display(f, self)?;
} }
......
...@@ -1108,7 +1108,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -1108,7 +1108,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
continue; 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; continue;
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc::ty::maps::Providers; use rustc::ty::maps::Providers;
use rustc::ty::{self, TyCtxt, Kind}; use rustc::ty::{self, TyCtxt};
use rustc::hir; use rustc::hir;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE}; 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 ...@@ -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 // FIXME: when we make this a hard error, this should have its
// own error code. // 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 \ format!("#[derive] can't be used on a #[repr(packed)] struct with \
type parameters (error E0133)") type parameters (error E0133)")
} else { } else {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
use rustc::hir::TransFnAttrFlags; use rustc::hir::TransFnAttrFlags;
use rustc::hir::def_id::{DefId, CrateNum}; use rustc::hir::def_id::{DefId, CrateNum};
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::ty::{Kind, GenericParamDef}; use rustc::ty::GenericParamDef;
use abi::Abi; use abi::Abi;
use common::CodegenCx; use common::CodegenCx;
...@@ -197,6 +197,12 @@ pub fn finalize(cx: &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. /// Creates the function-specific debug context.
/// ///
/// Returns the FunctionDebugContext for the function which holds state needed /// Returns the FunctionDebugContext for the function which holds state needed
......
...@@ -210,7 +210,7 @@ fn create_substs_for_ast_path(&self, ...@@ -210,7 +210,7 @@ fn create_substs_for_ast_path(&self,
let decl_generics = tcx.generics_of(def_id); let decl_generics = tcx.generics_of(def_id);
let param_counts = decl_generics.param_counts(); let param_counts = decl_generics.param_counts();
let num_types_provided = parameters.types.len(); 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(); let supplied_num_region_params = parameters.lifetimes.len();
if expected_num_region_params != supplied_num_region_params { if expected_num_region_params != supplied_num_region_params {
report_lifetime_number_error(tcx, span, report_lifetime_number_error(tcx, span,
...@@ -223,7 +223,7 @@ fn create_substs_for_ast_path(&self, ...@@ -223,7 +223,7 @@ fn create_substs_for_ast_path(&self,
// Check the number of type parameters supplied by the user. // Check the number of type parameters supplied by the user.
let type_params_offset = self_ty.is_some() as usize; 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 { if !infer_types || num_types_provided > ty_param_defs {
check_type_argument_count(tcx, check_type_argument_count(tcx,
span, span,
...@@ -260,7 +260,7 @@ fn create_substs_for_ast_path(&self, ...@@ -260,7 +260,7 @@ fn create_substs_for_ast_path(&self,
return ty; 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 { if i < num_types_provided {
// A provided type parameter. // A provided type parameter.
self.ast_ty_to_ty(&parameters.types[i]) self.ast_ty_to_ty(&parameters.types[i])
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
use rustc::hir::{self, ImplItemKind, TraitItemKind}; use rustc::hir::{self, ImplItemKind, TraitItemKind};
use rustc::infer::{self, InferOk}; use rustc::infer::{self, InferOk};
use rustc::ty::{self, TyCtxt, Kind}; use rustc::ty::{self, TyCtxt};
use rustc::ty::util::ExplicitSelf; use rustc::ty::util::ExplicitSelf;
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
use rustc::ty::error::{ExpectedFound, TypeError}; use rustc::ty::error::{ExpectedFound, TypeError};
...@@ -357,8 +357,8 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -357,8 +357,8 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
trait_to_skol_substs: &Substs<'tcx>) trait_to_skol_substs: &Substs<'tcx>)
-> Result<(), ErrorReported> { -> Result<(), ErrorReported> {
let span = tcx.sess.codemap().def_span(span); let span = tcx.sess.codemap().def_span(span);
let trait_params = trait_generics.param_counts()[&Kind::Lifetime]; let trait_params = trait_generics.param_counts().lifetimes;
let impl_params = impl_generics.param_counts()[&Kind::Lifetime]; let impl_params = impl_generics.param_counts().lifetimes;
debug!("check_region_bounds_on_impl_method: \ debug!("check_region_bounds_on_impl_method: \
trait_generics={:?} \ trait_generics={:?} \
...@@ -574,8 +574,8 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -574,8 +574,8 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-> Result<(), ErrorReported> { -> Result<(), ErrorReported> {
let impl_m_generics = tcx.generics_of(impl_m.def_id); let impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_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_impl_m_type_params = impl_m_generics.param_counts().types;
let num_trait_m_type_params = trait_m_generics.param_counts()[&Kind::Type]; let num_trait_m_type_params = trait_m_generics.param_counts().types;
if num_impl_m_type_params != num_trait_m_type_params { 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_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); let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
use intrinsics; use intrinsics;
use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::traits::{ObligationCause, ObligationCauseCode};
use rustc::ty::{self, TyCtxt, Ty, Kind}; use rustc::ty::{self, TyCtxt, Ty};
use rustc::util::nodemap::FxHashMap; use rustc::util::nodemap::FxHashMap;
use require_same_types; use require_same_types;
...@@ -45,7 +45,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -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 { if i_n_tps != n_tps {
let span = match it.node { let span = match it.node {
hir::ForeignItemFn(_, _, ref generics) => generics.span, hir::ForeignItemFn(_, _, ref generics) => generics.span,
...@@ -346,7 +346,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -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 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 name = it.name.as_str();
let (n_tps, inputs, output) = match &*name { let (n_tps, inputs, output) = match &*name {
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
use hir::def_id::DefId; use hir::def_id::DefId;
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::traits; use rustc::traits;
use rustc::ty::{self, Ty, Kind}; use rustc::ty::{self, Ty};
use rustc::ty::subst::Subst; use rustc::ty::subst::Subst;
use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref}; use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
...@@ -333,7 +333,7 @@ fn instantiate_method_substs(&mut self, ...@@ -333,7 +333,7 @@ fn instantiate_method_substs(&mut self,
} else if let Some(ast_ty) } else if let Some(ast_ty)
= provided.as_ref().and_then(|p| { = provided.as_ref().and_then(|p| {
let idx = 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) p.types.get(idx)
}) })
{ {
......
...@@ -1239,8 +1239,7 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item ...@@ -1239,8 +1239,7 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
} else { } else {
for item in &m.items { for item in &m.items {
let generics = tcx.generics_of(tcx.hir.local_def_id(item.id)); let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
let param_counts = generics.param_counts(); if generics.params.len() - generics.param_counts().lifetimes != 0 {
if generics.params.len() - param_counts[&ty::Kind::Lifetime] != 0 {
let mut err = struct_span_err!(tcx.sess, item.span, E0044, let mut err = struct_span_err!(tcx.sess, item.span, E0044,
"foreign items may not have type parameters"); "foreign items may not have type parameters");
err.span_label(item.span, "can't have type parameters"); err.span_label(item.span, "can't have type parameters");
...@@ -4800,7 +4799,7 @@ pub fn instantiate_value_path(&self, ...@@ -4800,7 +4799,7 @@ pub fn instantiate_value_path(&self,
// Skip over the lifetimes in the same segment. // Skip over the lifetimes in the same segment.
if let Some((_, generics)) = 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) { if let Some(ast_ty) = types.get(i) {
...@@ -4921,15 +4920,15 @@ fn check_path_parameter_count(&self, ...@@ -4921,15 +4920,15 @@ fn check_path_parameter_count(&self,
// Check provided parameters. // Check provided parameters.
let (ty_non_def_req_len, ty_req_len, lt_req_len) = let (ty_non_def_req_len, ty_req_len, lt_req_len) =
segment.map_or((0, 0, 0), |(_, generics)| { segment.map_or((0, 0, 0), |(_, generics)| {
let params_count = generics.param_counts(); let param_counts = generics.param_counts();
let type_params_offset let type_params_offset
= (generics.parent.is_none() && generics.has_self) as usize; = (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 = let type_params_barring_defaults =
generics.type_params_without_defaults() - type_params_offset; 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 { if types.len() > ty_req_len {
...@@ -5088,22 +5087,12 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -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; } if generics.ty_params().next().is_none() { return; }
let mut tps_used = vec![false; generics.ty_params().count()]; let mut tps_used = vec![false; generics.ty_params().count()];
let mut param_counts = FxHashMap(); let lifetime_count = generics.lifetimes().count();
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;
}
for leaf_ty in ty.walk() { 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); 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 { } else if let ty::TyError = leaf_ty.sty {
// If there already another error, do not emit an error for not using a type Parameter // If there already another error, do not emit an error for not using a type Parameter
assert!(tcx.sess.err_count() > 0); assert!(tcx.sess.err_count() > 0);
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::def_id::DefIndexAddressSpace; use rustc::hir::def_id::DefIndexAddressSpace;
use rustc::ty::subst::Substs; 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::middle::stability;
use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_typeck::hir_ty_to_ty; use rustc_typeck::hir_ty_to_ty;
...@@ -2684,31 +2684,34 @@ fn clean(&self, cx: &DocContext) -> Type { ...@@ -2684,31 +2684,34 @@ fn clean(&self, cx: &DocContext) -> Type {
let mut ty_substs = FxHashMap(); let mut ty_substs = FxHashMap();
let mut lt_substs = FxHashMap(); let mut lt_substs = FxHashMap();
provided_params.with_parameters(|provided_params| { provided_params.with_parameters(|provided_params| {
let mut indices = FxHashMap(); let mut indices = GenericParamCount {
lifetimes: 0,
types: 0
};
for param in generics.params.iter() { for param in generics.params.iter() {
match param { match param {
hir::GenericParam::Lifetime(lt_param) => {
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));
}
}
indices.lifetimes += 1;
}
hir::GenericParam::Type(ty_param) => { hir::GenericParam::Type(ty_param) => {
let i = indices.entry(Kind::Type).or_insert(0);
let ty_param_def = let ty_param_def =
Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id)); Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
if let Some(ty) = provided_params.types.get(*i).cloned() { if let Some(ty) = provided_params.types
.get(indices.types).cloned() {
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx)); ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
} else if let Some(default) = ty_param.default.clone() { } else if let Some(default) = ty_param.default.clone() {
ty_substs.insert(ty_param_def, ty_substs.insert(ty_param_def,
default.into_inner().clean(cx)); default.into_inner().clean(cx));
} }
*i += 1; indices.types += 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 !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;
} }
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册