From e94fab33da44f5fda873b61e964d9141891c4ad9 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 | 17 +++++++++++++-- .../assoc-type-maybe-trait-147356.rs | 16 ++++++++++++++ .../assoc-type-maybe-trait-147356.stderr | 21 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 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 8c2ddda7f9834..91bf7efa82050 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -934,7 +934,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } fn suggest_trait_and_bounds( - &self, + &mut self, err: &mut Diag<'_>, source: PathSource<'_, '_, '_>, res: Option, @@ -1479,7 +1479,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } /// Given `where ::Baz: String`, suggest `where T: Bar`. - fn restrict_assoc_type_in_where_clause(&self, span: Span, err: &mut Diag<'_>) -> bool { + fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diag<'_>) -> bool { // Detect that we are actually in a `where` predicate. let (bounded_ty, bounds, where_span) = if let Some(ast::WherePredicate { kind: @@ -1539,6 +1539,19 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &poly_trait_ref.trait_ref.path.segments[..] { if ident.span == span { + if matches!( + self.resolve_path( + &[Segment::from_ident(*ident)], + Some(TypeNS), + None, + PathSource::Type, + ), + PathResult::Indeterminate | PathResult::Failed { .. } + ) { + // if the ident doesn't resolve to a type, don't suggest constrain associated type. + return false; + } + let Some(new_where_bound_predicate) = mk_where_bound_predicate(path, poly_trait_ref, ty) else { 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`.