From 76bd555913eb9d363bf76136e1767f08f2c06bdb Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 5 Oct 2025 12:03:17 +0800 Subject: [PATCH] Avoid suggesting constrain the associated type to a trait --- .../rustc_resolve/src/late/diagnostics.rs | 37 +++++++++++-------- .../assoc-type-maybe-trait-147356.rs | 16 ++++++++ .../assoc-type-maybe-trait-147356.stderr | 21 +++++++++++ 3 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.rs create mode 100644 tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index da58c923695dd..08976ce4feea5 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1572,26 +1572,31 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { [ast::PathSegment { args: None, .. }], [ast::GenericBound::Trait(poly_trait_ref)], ) = (&type_param_path.segments[..], &bounds[..]) + && let [ast::PathSegment { ident, args: None, id }] = + &poly_trait_ref.trait_ref.path.segments[..] && poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE { - if let [ast::PathSegment { ident, args: None, .. }] = - &poly_trait_ref.trait_ref.path.segments[..] - { - if ident.span == span { - let Some(new_where_bound_predicate) = - mk_where_bound_predicate(path, poly_trait_ref, ty) - else { - return false; - }; - err.span_suggestion_verbose( - *where_span, - format!("constrain the associated type to `{ident}`"), - where_bound_predicate_to_string(&new_where_bound_predicate), - Applicability::MaybeIncorrect, - ); + if ident.span == span { + let Some(partial_res) = self.r.partial_res_map.get(&id) else { + return false; + }; + if !matches!(partial_res.full_res(), Some(hir::def::Res::Def(..))) { + return false; } - return true; + + let Some(new_where_bound_predicate) = + mk_where_bound_predicate(path, poly_trait_ref, ty) + else { + return false; + }; + err.span_suggestion_verbose( + *where_span, + format!("constrain the associated type to `{ident}`"), + where_bound_predicate_to_string(&new_where_bound_predicate), + Applicability::MaybeIncorrect, + ); } + return true; } } false diff --git a/tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.rs b/tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.rs new file mode 100644 index 0000000000000..8d8eab308ba23 --- /dev/null +++ b/tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.rs @@ -0,0 +1,16 @@ +use std::str::FromStr; +fn foo() -> T +where + ::Err: Debug, //~ ERROR expected trait +{ + "".parse().unwrap() +} + +fn bar() -> T +where + ::Err: some_unknown_name, //~ ERROR cannot find trait `some_unknown_name` in this scope +{ + "".parse().unwrap() +} + +fn main() {} diff --git a/tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.stderr b/tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.stderr new file mode 100644 index 0000000000000..b7fc85af82407 --- /dev/null +++ b/tests/ui/traits/associated_type_bound/assoc-type-maybe-trait-147356.stderr @@ -0,0 +1,21 @@ +error[E0404]: expected trait, found derive macro `Debug` + --> $DIR/assoc-type-maybe-trait-147356.rs:4:26 + | +LL | ::Err: Debug, + | ^^^^^ not a trait + | +help: consider importing this trait instead + | +LL + use std::fmt::Debug; + | + +error[E0405]: cannot find trait `some_unknown_name` in this scope + --> $DIR/assoc-type-maybe-trait-147356.rs:11:26 + | +LL | ::Err: some_unknown_name, + | ^^^^^^^^^^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0404, E0405. +For more information about an error, try `rustc --explain E0404`.