提交 9200bdee 编写于 作者: V varkor

Refactor generic params loops

上级 18f77e25
......@@ -374,8 +374,8 @@ fn visit_item(&mut self, item: &'lcx Item) {
if item_lowered {
let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
hir::Item_::ItemImpl(_, _, _, ref generics, .. ) |
hir::Item_::ItemTrait(_, _, ref generics, .. ) => {
hir::Item_::ItemImpl(_, _, _, ref generics, ..)
| hir::Item_::ItemTrait(_, _, ref generics, ..) => {
generics.lifetimes().cloned().collect::<Vec<_>>()
}
_ => Vec::new(),
......@@ -1895,13 +1895,11 @@ fn lower_generic_params(
GenericParam::Lifetime(ref lifetime_def) => {
hir::GenericParam::Lifetime(self.lower_lifetime_def(lifetime_def))
}
GenericParam::Type(ref ty_param) => {
hir::GenericParam::Type(self.lower_ty_param(
ty_param,
add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x),
itctx,
))
}
GenericParam::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param(
ty_param,
add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x),
itctx,
)),
})
.collect()
}
......
......@@ -2043,10 +2043,7 @@ pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<
Ok(())
}
pub fn print_generic_params(&mut self,
generic_params: &[hir::GenericParam])
-> io::Result<()>
{
pub fn print_generic_params(&mut self, generic_params: &[hir::GenericParam]) -> io::Result<()> {
if !generic_params.is_empty() {
self.s.word("<")?;
......
......@@ -313,16 +313,13 @@ fn constrain_anon_type<FRR: FreeRegionRelations<'tcx>>(
// `['a]` for the first impl trait and `'b` for the
// second.
let mut least_region = None;
for index in abstract_type_generics.params.iter().filter_map(|param| {
if let GenericParamDefKind::Lifetime(_) = param.kind {
// Find the index of this region in the list of substitutions.
Some(param.index as usize)
} else {
None
for param in &abstract_type_generics.params {
match param.kind {
GenericParamDefKind::Lifetime(_) => {}
_ => continue
}
}) {
// Get the value supplied for this region from the substs.
let subst_arg = anon_defn.substs.region_at(index);
let subst_arg = anon_defn.substs.region_at(param.index as usize);
// Compute the least upper bound of it with the other regions.
debug!("constrain_anon_types: least_region={:?}", least_region);
......
......@@ -222,9 +222,14 @@ pub fn find_auto_trait_generics<A>(
});
let names_map: FxHashSet<String> = generics
.regions
.params
.iter()
.map(|l| l.name.to_string())
.filter_map(|param| {
match param.kind {
ty::GenericParamDefKind::Lifetime(_) => Some(param.name.to_string()),
_ => None
}
})
.collect();
let body_ids: FxHashSet<_> = infcx
......
......@@ -379,16 +379,16 @@ fn on_unimplemented_note(
flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string())));
}
for param in generics.params.iter().filter(|param| {
match param.kind {
GenericParamDefKind::Type(_) => true,
GenericParamDefKind::Lifetime(_) => false,
}
}) {
for param in generics.params.iter() {
let name = param.name.to_string();
let ty = trait_ref.substs.type_for_def(&param);
let ty_str = ty.to_string();
flags.push((name.clone(), Some(ty_str.clone())));
let value = match param.kind {
GenericParamDefKind::Type(_) => {
let ty = trait_ref.substs.type_for_def(&param);
ty.to_string()
},
GenericParamDefKind::Lifetime(_) => continue,
};
flags.push((name.clone(), Some(value.clone())));
}
if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) {
......
......@@ -254,15 +254,12 @@ fn verify(&self,
Position::ArgumentNamed(s) if s == name => (),
// So is `{A}` if A is a type parameter
Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
match param.kind {
GenericParamDefKind::Type(_) => param.name == s,
GenericParamDefKind::Lifetime(_) => false,
}
param.name == s
}) {
Some(_) => (),
None => {
span_err!(tcx.sess, span, E0230,
"there is no type parameter \
"there is no parameter \
{} on trait {}",
s, name);
result = Err(ErrorReported);
......
......@@ -35,7 +35,6 @@
use ty::subst::{Kind, Substs, Subst};
use ty::ReprOptions;
use ty::Instance;
use ty::GenericParamDefKind;
use traits;
use traits::{Clause, Clauses, Goal, Goals};
use ty::{self, Ty, TypeAndMut};
......@@ -2326,20 +2325,19 @@ pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> {
pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
let adt_def = self.adt_def(def_id);
let generics = self.generics_of(def_id);
let mut substs = vec![Kind::from(ty)];
// Add defaults for other generic params if there are some.
for (def_id, has_default) in generics.params.iter().filter_map(|param| {
match param.kind {
GenericParamDefKind::Type(ty) => Some((param.def_id, ty.has_default)),
GenericParamDefKind::Lifetime(_) => None
let substs = Substs::for_item(self, def_id, |_, _| bug!(), |def, substs| {
if def.index == 0 {
ty
} else {
match def.kind {
ty::GenericParamDefKind::Type(ty_param) => {
assert!(ty_param.has_default);
self.type_of(def.def_id).subst(self, substs)
}
_ => unreachable!()
}
}
}).skip(1) {
assert!(has_default);
let ty = self.type_of(def_id).subst(self, &substs);
substs.push(ty.into());
}
let substs = self.mk_substs(substs.into_iter());
});
self.mk_ty(TyAdt(adt_def, substs))
}
......
......@@ -804,7 +804,7 @@ pub struct Generics {
pub parent_count: usize,
pub params: Vec<GenericParamDef>,
/// Reverse map to the `index` field of each `GenericParamDef`'s inner type
/// Reverse map to the `index` field of each `GenericParamDef`
pub param_def_id_to_index: FxHashMap<DefId, u32>,
pub has_self: bool,
......@@ -836,13 +836,11 @@ pub fn param_counts(&self) -> GenericParamCount {
}
pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
if self.params.iter().any(|param| {
for param in self.params.iter() {
match param.kind {
GenericParamDefKind::Type(_) => true,
GenericParamDefKind::Lifetime(_) => false
GenericParamDefKind::Type(_) => return true,
GenericParamDefKind::Lifetime(_) => {}
}
}) {
return true;
}
if let Some(parent_def_id) = self.parent {
let parent = tcx.generics_of(parent_def_id);
......@@ -858,7 +856,7 @@ pub fn region_param(&'tcx self,
-> &'tcx GenericParamDef
{
if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
let ref param = self.params[index as usize];
let param = &self.params[index as usize];
match param.kind {
ty::GenericParamDefKind::Lifetime(_) => param,
_ => bug!("expected region parameter, but found another generic parameter")
......@@ -875,53 +873,7 @@ pub fn type_param(&'tcx self,
tcx: TyCtxt<'a, 'gcx, 'tcx>)
-> &'tcx GenericParamDef {
if let Some(index) = param.idx.checked_sub(self.parent_count as u32) {
// non-Self type parameters are always offset by exactly
// `self.regions.len()`. In the absence of a Self, this is obvious,
// but even in the presence of a `Self` we just have to "compensate"
// for the regions:
//
// Without a `Self` (or in a nested generics that doesn't have
// a `Self` in itself, even through it parent does), for example
// for `fn foo<'a, T1, T2>()`, the situation is:
// Substs:
// 0 1 2
// 'a T1 T2
// generics.types:
// 0 1
// T1 T2
//
// And with a `Self`, for example for `trait Foo<'a, 'b, T1, T2>`, the
// situation is:
// Substs:
// 0 1 2 3 4
// Self 'a 'b T1 T2
// generics.types:
// 0 1 2
// Self T1 T2
//
// 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().lifetimes;
let has_self = self.has_self && self.parent.is_none();
let is_separated_self = type_param_offset != 0 && index == 0 && has_self;
if let Some(_) = (index as usize).checked_sub(type_param_offset) {
assert!(!is_separated_self, "found a Self after type_param_offset");
let ref param = self.params[index as usize];
match param.kind {
ty::GenericParamDefKind::Type(_) => param,
_ => bug!("expected type parameter, but found another generic parameter")
}
} else {
assert!(is_separated_self, "non-Self param before type_param_offset");
let ref param = self.params[type_param_offset];
match param.kind {
ty::GenericParamDefKind::Type(_) => param,
_ => bug!("expected type parameter, but found another generic parameter")
}
}
&self.params[index as usize]
} else {
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
.type_param(param, tcx)
......
......@@ -366,7 +366,7 @@ struct SplitGeneratorSubsts<'tcx> {
impl<'tcx> GeneratorSubsts<'tcx> {
fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitGeneratorSubsts<'tcx> {
let generics = tcx.generics_of(def_id);
let parent_len = generics.parent_count();
let parent_len = generics.parent_count;
SplitGeneratorSubsts {
yield_ty: self.substs.type_at(parent_len),
return_ty: self.substs.type_at(parent_len + 1),
......
......@@ -351,8 +351,10 @@ fn parameterized<F: fmt::Write>(&mut self,
let zipped = iter::once((last_ty, types.next().unwrap()))
.chain(type_params.zip(types));
for ((def_id, has_default), actual) in zipped {
if !has_default ||
tcx.type_of(def_id).subst(tcx, substs) != actual {
if !has_default {
break;
}
if tcx.type_of(def_id).subst(tcx, substs) != actual {
break;
}
num_supplied_defaults += 1;
......@@ -604,7 +606,7 @@ fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result
impl fmt::Debug for ty::GenericParamDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let type_name = match self.kind {
ty::GenericParamDefKind::Lifetime(_) => "Region",
ty::GenericParamDefKind::Lifetime(_) => "Lifetime",
ty::GenericParamDefKind::Type(_) => "Type",
};
write!(f, "{}({}, {:?}, {})",
......
......@@ -399,7 +399,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
fn generics(&mut self) -> &mut Self {
for param in self.ev.tcx.generics_of(self.item_def_id).params.iter() {
for param in &self.ev.tcx.generics_of(self.item_def_id).params {
match param.kind {
GenericParamDefKind::Type(ty) => {
if ty.has_default {
......@@ -1340,7 +1340,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
fn generics(&mut self) -> &mut Self {
for param in self.tcx.generics_of(self.item_def_id).params.iter() {
for param in &self.tcx.generics_of(self.item_def_id).params {
match param.kind {
GenericParamDefKind::Type(ty) => {
if ty.has_default {
......
......@@ -222,8 +222,8 @@ fn create_substs_for_ast_path(&self,
assert_eq!(decl_generics.has_self, self_ty.is_some());
// 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.types - type_params_offset;
let own_self = self_ty.is_some() as usize;
let ty_param_defs = param_counts.types - own_self;
if !infer_types || num_types_provided > ty_param_defs {
let type_params_without_defaults = {
let mut count = 0;
......@@ -241,7 +241,7 @@ fn create_substs_for_ast_path(&self,
span,
num_types_provided,
ty_param_defs,
type_params_without_defaults - type_params_offset);
type_params_without_defaults - own_self);
}
let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
......@@ -258,7 +258,7 @@ fn create_substs_for_ast_path(&self,
};
let substs = Substs::for_item(tcx, def_id, |def, _| {
let i = def.index as usize - type_params_offset;
let i = def.index as usize - own_self;
if let Some(lifetime) = parameters.lifetimes.get(i) {
self.ast_region_to_region(lifetime, Some(def))
} else {
......@@ -272,7 +272,7 @@ fn create_substs_for_ast_path(&self,
return ty;
}
let i = i - (param_counts.lifetimes + type_params_offset);
let i = i - (param_counts.lifetimes + own_self);
if i < num_types_provided {
// A provided type parameter.
self.ast_ty_to_ty(&parameters.types[i])
......
......@@ -316,6 +316,7 @@ fn instantiate_method_substs(&mut self,
// parameters from the type and those from the method.
assert_eq!(method_generics.parent_count, parent_substs.len());
let provided = &segment.parameters;
let param_counts = method_generics.param_counts();
Substs::for_item(self.tcx, pick.item.def_id, |def, _| {
let i = def.index as usize;
if i < parent_substs.len() {
......@@ -333,7 +334,7 @@ fn instantiate_method_substs(&mut self,
} else if let Some(ast_ty)
= provided.as_ref().and_then(|p| {
let idx =
i - parent_substs.len() - method_generics.param_counts().lifetimes;
i - parent_substs.len() - param_counts.lifetimes;
p.types.get(idx)
})
{
......
......@@ -4918,13 +4918,12 @@ fn check_path_parameter_count(&self,
};
// Check provided parameters.
let (ty_non_def_req_len, ty_req_len, lt_req_len) =
let (ty_req_len, accepted, lt_req_len) =
segment.map_or((0, 0, 0), |(_, generics)| {
let param_counts = generics.param_counts();
let type_params_offset
= (generics.parent.is_none() && generics.has_self) as usize;
let type_params = param_counts.types - type_params_offset;
let own_self = (generics.parent.is_none() && generics.has_self) as usize;
let type_params = param_counts.types - own_self;
let type_params_without_defaults = {
let mut count = 0;
for param in generics.params.iter() {
......@@ -4937,14 +4936,14 @@ fn check_path_parameter_count(&self,
count
};
let type_params_barring_defaults =
type_params_without_defaults - type_params_offset;
type_params_without_defaults - own_self;
(type_params_barring_defaults, type_params, param_counts.lifetimes)
});
if types.len() > ty_req_len {
let span = types[ty_req_len].span;
let expected_text = count_type_params(ty_req_len);
if types.len() > accepted {
let span = types[accepted].span;
let expected_text = count_type_params(accepted);
let actual_text = count_type_params(types.len());
struct_span_err!(self.tcx.sess, span, E0087,
"too many type parameters provided: \
......@@ -4957,8 +4956,8 @@ fn check_path_parameter_count(&self,
// type parameters, we force instantiate_value_path to
// use inference variables instead of the provided types.
*segment = None;
} else if types.len() < ty_non_def_req_len && !infer_types && !supress_mismatch_error {
let expected_text = count_type_params(ty_non_def_req_len);
} else if types.len() < ty_req_len && !infer_types && !supress_mismatch_error {
let expected_text = count_type_params(ty_req_len);
let actual_text = count_type_params(types.len());
struct_span_err!(self.tcx.sess, span, E0089,
"too few type parameters provided: \
......
......@@ -378,22 +378,19 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
// For example this forbids the declaration:
// struct Foo<T = Vec<[u32]>> { .. }
// Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
for d in generics.params.iter().filter_map(|param| {
for param in &generics.params {
if let GenericParamDefKind::Type(_) = param.kind {
if is_our_default(&param) {
return Some(param.def_id);
let ty = fcx.tcx.type_of(param.def_id);
// ignore dependent defaults -- that is, where the default of one type
// parameter includes another (e.g., <T, U = T>). In those cases, we can't
// be sure if it will error or not as user might always specify the other.
if !ty.needs_subst() {
fcx.register_wf_obligation(ty, fcx.tcx.def_span(param.def_id),
ObligationCauseCode::MiscObligation);
}
}
}
None
}) {
let ty = fcx.tcx.type_of(d);
// ignore dependent defaults -- that is, where the default of one type
// parameter includes another (e.g., <T, U = T>). In those cases, we can't
// be sure if it will error or not as user might always specify the other.
if !ty.needs_subst() {
fcx.register_wf_obligation(ty, fcx.tcx.def_span(d),
ObligationCauseCode::MiscObligation);
}
}
// Check that trait predicates are WF when params are substituted by their defaults.
......@@ -662,20 +659,20 @@ fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
.collect();
for method_param in generics.params.iter() {
let (name, def_id) = match method_param.kind {
match method_param.kind {
// Shadowing is checked in resolve_lifetime.
GenericParamDefKind::Lifetime(_) => continue,
GenericParamDefKind::Type(_) => (method_param.name, method_param.def_id),
_ => {},
};
if impl_params.contains_key(&name) {
if impl_params.contains_key(&method_param.name) {
// Tighten up the span to focus on only the shadowing type
let type_span = tcx.def_span(def_id);
let type_span = tcx.def_span(method_param.def_id);
// The expectation here is that the original trait declaration is
// local so it should be okay to just unwrap everything.
let trait_def_id = impl_params[&name];
let trait_def_id = impl_params[&method_param.name];
let trait_decl_span = tcx.def_span(trait_def_id);
error_194(tcx, type_span, trait_decl_span, &name.as_str()[..]);
error_194(tcx, type_span, trait_decl_span, &method_param.name.as_str()[..]);
}
}
}
......
......@@ -903,7 +903,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Now create the real type parameters.
let type_start = own_start + lifetimes.len() as u32;
let types = ast_generics.ty_params().enumerate().map(|(i, p)| {
let mut types: Vec<_> = ast_generics.ty_params().enumerate().map(|(i, p)| {
if p.name == keywords::SelfType.name() {
span_bug!(p.span, "`Self` should not be the name of a regular parameter");
}
......@@ -931,9 +931,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
synthetic: p.synthetic,
}),
}
});
let mut types: Vec<_> = types.into_iter().collect();
}).collect();
// provide junk type parameter defs - the only place that
// cares about anything but the length is instantiation,
......
......@@ -1753,7 +1753,7 @@ fn clean(&self, cx: &DocContext) -> Generics {
let mut params = Vec::with_capacity(self.params.len());
for p in &self.params {
let p = p.clean(cx);
if let GenericParam::Type(ref tp) = p {
if let GenericParamDef::Type(ref tp) = p {
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
cx.impl_trait_bounds.borrow_mut().insert(tp.did, tp.bounds.clone());
}
......
......@@ -72,9 +72,7 @@ fn visit_pat(&mut self, p: &'ast Pat) { walk_pat(self, p) }
fn visit_expr(&mut self, ex: &'ast Expr) { walk_expr(self, ex) }
fn visit_expr_post(&mut self, _ex: &'ast Expr) { }
fn visit_ty(&mut self, t: &'ast Ty) { walk_ty(self, t) }
fn visit_generic_param(&mut self, param: &'ast GenericParam) {
walk_generic_param(self, param)
}
fn visit_generic_param(&mut self, param: &'ast GenericParam) { walk_generic_param(self, param) }
fn visit_generics(&mut self, g: &'ast Generics) { walk_generics(self, g) }
fn visit_where_predicate(&mut self, p: &'ast WherePredicate) {
walk_where_predicate(self, p)
......
......@@ -570,11 +570,7 @@ fn create_derived_impl(&self,
bounds.push((*declared_bound).clone());
}
GenericParam::Type(cx.typaram(self.span,
ty_param.ident,
vec![],
bounds,
None))
GenericParam::Type(cx.typaram(self.span, ty_param.ident, vec![], bounds, None))
}
}
}));
......
......@@ -187,9 +187,7 @@ pub fn to_path(&self,
let self_params = self_generics.params
.iter()
.filter_map(|param| match *param {
GenericParam::Type(ref ty_param) => {
Some(cx.ty_ident(span, ty_param.ident))
}
GenericParam::Type(ref ty_param) => Some(cx.ty_ident(span, ty_param.ident)),
_ => None,
})
.collect();
......@@ -272,10 +270,7 @@ pub fn to_generics(&self,
let bounds = bounds.iter()
.map(|b| cx.lifetime(span, Ident::from_str(b)))
.collect();
GenericParam::Lifetime(cx.lifetime_def(span,
Ident::from_str(lt),
vec![],
bounds))
GenericParam::Lifetime(cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds))
})
.chain(self.bounds
.iter()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册