1
Fork 0

Simplify the collecting of ? Trait bounds in where clause

This commit is contained in:
surechen 2021-07-21 11:35:06 +08:00
parent b41936b92c
commit 7af840f62e

View file

@ -1373,50 +1373,37 @@ impl<'hir> LoweringContext<'_, 'hir> {
itctx: ImplTraitContext<'_, 'hir>, itctx: ImplTraitContext<'_, 'hir>,
) -> GenericsCtor<'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.
// FIXME: this could probably be done with less rightward drift. It also looks like two
// control paths where `report_error` is called are the only paths that advance to after the
// match statement, so the error reporting could probably just be moved there.
let mut add_bounds: NodeMap<Vec<_>> = Default::default(); let mut add_bounds: NodeMap<Vec<_>> = Default::default();
for pred in &generics.where_clause.predicates { for pred in &generics.where_clause.predicates {
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred { if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
'next_bound: for bound in &bound_pred.bounds { 'next_bound: for bound in &bound_pred.bounds {
if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound { if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
let report_error = |this: &mut Self| {
this.diagnostic().span_err(
bound_pred.bounded_ty.span,
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
};
// Check if the where clause type is a plain type parameter. // Check if the where clause type is a plain type parameter.
match bound_pred.bounded_ty.kind { match self
TyKind::Path(None, ref path) .resolver
if path.segments.len() == 1 .get_partial_res(bound_pred.bounded_ty.id)
&& bound_pred.bound_generic_params.is_empty() => .map(|d| (d.base_res(), d.unresolved_segments()))
{ {
if let Some(Res::Def(DefKind::TyParam, def_id)) = self Some((Res::Def(DefKind::TyParam, def_id), 0))
.resolver if bound_pred.bound_generic_params.is_empty() =>
.get_partial_res(bound_pred.bounded_ty.id)
.map(|d| d.base_res())
{ {
if let Some(def_id) = def_id.as_local() { for param in &generics.params {
for param in &generics.params { if def_id == self.resolver.local_def_id(param.id).to_def_id() {
if let GenericParamKind::Type { .. } = param.kind { add_bounds
if def_id == self.resolver.local_def_id(param.id) { .entry(param.id)
add_bounds .or_default()
.entry(param.id) .push(bound.clone());
.or_default() continue 'next_bound;
.push(bound.clone());
continue 'next_bound;
}
}
} }
} }
} }
report_error(self) _ => {}
}
_ => report_error(self),
} }
self.diagnostic().span_err(
bound_pred.bounded_ty.span,
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
} }
} }
} }