diff options
| author | bors <bors@rust-lang.org> | 2021-07-24 02:30:35 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-07-24 02:30:35 +0000 |
| commit | d03456db5c8b3ff8dcfc31b45ddb49e66f34ab47 (patch) | |
| tree | b2c412bfde29d3ba3692771aca0ae6086ec57808 | |
| parent | 3b4a0dfc139872341a2b55ee9958f6fa8a9f1d64 (diff) | |
| parent | 0f5bfc22423f8b0a313a19fef92fdeb872f8cd11 (diff) | |
| download | rust-d03456db5c8b3ff8dcfc31b45ddb49e66f34ab47.tar.gz rust-d03456db5c8b3ff8dcfc31b45ddb49e66f34ab47.zip | |
Auto merge of #87338 - SparrowLii:MaybeTrait, r=wesleywiser
Simplify the collecting of `? Trait` bounds in where clause
This PR fixes the FIXME about using less rightward drift and only one error reporting when collecting of `?Trait` bounds in where clause.
Checking whether the path length of `bound_ty` is 1 can be replaced by whether `unresolved_segments` in the partial_res is 0.
Checking whether the `param.kind` is `Type{...}` can also be omitted. One Fx hash calculation will be done for Const or Lifetime param, but the impact on efficiency should be small IMO
| -rw-r--r-- | compiler/rustc_ast_lowering/src/item.rs | 50 |
1 files changed, 17 insertions, 33 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 9f9d41c3f3d..880692516e9 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1373,50 +1373,34 @@ impl<'hir> LoweringContext<'_, 'hir> { itctx: ImplTraitContext<'_, 'hir>, ) -> GenericsCtor<'hir> { // 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(); 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 { - 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. - match bound_pred.bounded_ty.kind { - TyKind::Path(None, ref path) - if path.segments.len() == 1 - && bound_pred.bound_generic_params.is_empty() => + 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(Res::Def(DefKind::TyParam, def_id)) = self - .resolver - .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 { - if let GenericParamKind::Type { .. } = param.kind { - if def_id == self.resolver.local_def_id(param.id) { - add_bounds - .entry(param.id) - .or_default() - .push(bound.clone()); - continue 'next_bound; - } - } - } + 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; } } - 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", + ); } } } |
