From 0771f9c1ccf0eec6347003923167f5d8a67bdd3d Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Sat, 24 Jul 2021 20:54:48 -0500 Subject: [PATCH] refactor LoweringContext::lower_generics_mut Further reduce nesting by using early exits and replacing the innermost loop with `.find()`. Also eliminates the labeled branch. Add comments explaining why the copying of `?Sized` bounds is necessary. --- compiler/rustc_ast_lowering/src/item.rs | 61 +++++++++++++++---------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 880692516e9ef..89e8416087957 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1372,37 +1372,48 @@ impl<'hir> LoweringContext<'_, 'hir> { generics: &Generics, itctx: ImplTraitContext<'_, 'hir>, ) -> GenericsCtor<'hir> { - // Collect `?Trait` bounds in where clause and move them to parameter definitions. + // Collect `?Trait` bounds in where clause and move them to parameter + // definitions. Currently, the decision to add the predicate for the + // implicit `Sized` bound only examines the generic parameters, not the + // where clauses, to discover any `?Sized` bounds. (e.g., + // `AstConv::is_unsized`) let mut add_bounds: NodeMap> = Default::default(); for pred in &generics.where_clause.predicates { - if let WherePredicate::BoundPredicate(ref bound_pred) = *pred { - 'next_bound: for bound in &bound_pred.bounds { - if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound { - // Check if the where clause type is a plain type parameter. - match self - .resolver - .get_partial_res(bound_pred.bounded_ty.id) - .map(|d| (d.base_res(), d.unresolved_segments())) + let bound_pred = match *pred { + WherePredicate::BoundPredicate(ref bound_pred) => bound_pred, + _ => continue, + }; + for bound in &bound_pred.bounds { + if !matches!(*bound, GenericBound::Trait(_, TraitBoundModifier::Maybe)) { + continue; + } + // Check if the where clause type is a plain type parameter. + match self + .resolver + .get_partial_res(bound_pred.bounded_ty.id) + .map(|d| (d.base_res(), d.unresolved_segments())) + { + Some((Res::Def(DefKind::TyParam, def_id), 0)) + if bound_pred.bound_generic_params.is_empty() => + { + if let Some(param) = generics + .params + .iter() + .find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id()) { - Some((Res::Def(DefKind::TyParam, def_id), 0)) - if bound_pred.bound_generic_params.is_empty() => - { - for param in &generics.params { - if def_id == self.resolver.local_def_id(param.id).to_def_id() { - add_bounds.entry(param.id).or_default().push(bound.clone()); - continue 'next_bound; - } - } - } - _ => {} + add_bounds.entry(param.id).or_default().push(bound.clone()); + continue; } - self.diagnostic().span_err( - bound_pred.bounded_ty.span, - "`?Trait` bounds are only permitted at the \ - point where a type parameter is declared", - ); } + _ => {} } + // Either the `bounded_ty` is not a plain type parameter, or + // it's not found in the generic type parameters list. + self.diagnostic().span_err( + bound_pred.bounded_ty.span, + "`?Trait` bounds are only permitted at the \ + point where a type parameter is declared", + ); } }