diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 9abae33ffdbb9..646ff3ca08d24 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -447,17 +447,30 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) { let mut parents = self.tcx().hir_parent_iter(self_ty.hir_id); - if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next() + if let Some((c_hir_id, hir::Node::AssocItemConstraint(constraint))) = parents.next() && let Some(obj_ty) = constraint.ty() + && let Some((_, hir::Node::TraitRef(trait_ref))) = parents.next() { - if let Some((_, hir::Node::TraitRef(..))) = parents.next() - && let Some((_, hir::Node::Ty(ty))) = parents.next() + if let Some((_, hir::Node::Ty(ty))) = parents.next() && let hir::TyKind::TraitObject(..) = ty.kind { // Assoc ty bounds aren't permitted inside trait object types. return; } + if trait_ref + .path + .segments + .iter() + .find_map(|seg| { + seg.args.filter(|args| args.constraints.iter().any(|c| c.hir_id == c_hir_id)) + }) + .is_none_or(|args| args.parenthesized != hir::GenericArgsParentheses::No) + { + // Only consider angle-bracketed args (where we have a `=` to replace with `:`). + return; + } + let lo = if constraint.gen_args.span_ext.is_dummy() { constraint.ident.span } else { diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs index c8bb0ebd5744b..49e46f44cb2f8 100644 --- a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs +++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs @@ -1,4 +1,4 @@ -// Regression test for issue #105056. +// issue: //@ edition: 2021 fn f(_: impl Trait) {} @@ -23,4 +23,11 @@ type Obj = dyn Trait; trait Trait { type T; } +// Don't suggest assoc ty bounds when we have parenthesized args (the underlying assoc type +// binding `Output` isn't introduced by `=` but by `->`, suggesting `:` wouldn't be valid). +// issue: +fn i(_: impl Fn() -> std::fmt::Debug) {} +//~^ ERROR expected a type, found a trait +//~| HELP you can add the `dyn` keyword if you want a trait object + fn main() {} diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr index 6eb8fabb1852c..ea9f25f07194b 100644 --- a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr +++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr @@ -57,6 +57,17 @@ help: you can add the `dyn` keyword if you want a trait object LL | type Obj = dyn Trait; | +++ -error: aborting due to 4 previous errors +error[E0782]: expected a type, found a trait + --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:29:22 + | +LL | fn i(_: impl Fn() -> std::fmt::Debug) {} + | ^^^^^^^^^^^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | fn i(_: impl Fn() -> dyn std::fmt::Debug) {} + | +++ + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0782`.