Simplify the collecting of ? Trait
bounds in where clause
This commit is contained in:
parent
b41936b92c
commit
7af840f62e
1 changed files with 20 additions and 33 deletions
|
@ -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",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue