From b205a5a67c3ababf7e7d6f47fe667f4dd5f12e58 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 25 Oct 2022 14:46:14 -0700 Subject: [PATCH 1/2] diagnostics: do not suggest static candidates as traits to import If it's a static candidate, then it's already implemented. Do not suggest it a second time for implementing. --- .../rustc_hir_typeck/src/method/suggest.rs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index f4351bfa84a..6c21ed902d0 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -106,7 +106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let report_candidates = |span: Span, err: &mut Diagnostic, - mut sources: Vec, + sources: &mut Vec, sugg_span: Span| { sources.sort(); sources.dedup(); @@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match error { MethodError::NoMatch(NoMatchData { - static_candidates: static_sources, + static_candidates: mut static_sources, unsatisfied_predicates, out_of_scope_traits, lev_candidate, @@ -422,9 +422,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.help(&format!("try with `{}::{}`", ty_str, item_name,)); } - report_candidates(span, &mut err, static_sources, sugg_span); + report_candidates(span, &mut err, &mut static_sources, sugg_span); } else if static_sources.len() > 1 { - report_candidates(span, &mut err, static_sources, sugg_span); + report_candidates(span, &mut err, &mut static_sources, sugg_span); } let mut bound_spans = vec![]; @@ -1007,6 +1007,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source, out_of_scope_traits, &unsatisfied_predicates, + &static_sources, unsatisfied_bounds, ); } @@ -1079,7 +1080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Some(err); } - MethodError::Ambiguity(sources) => { + MethodError::Ambiguity(mut sources) => { let mut err = struct_span_err!( self.sess(), item_name.span, @@ -1088,7 +1089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_label(item_name.span, format!("multiple `{}` found", item_name)); - report_candidates(span, &mut err, sources, sugg_span); + report_candidates(span, &mut err, &mut sources, sugg_span); err.emit(); } @@ -2015,6 +2016,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Option>, Option>, )], + static_candidates: &[CandidateSource], unsatisfied_bounds: bool, ) { let mut alt_rcvr_sugg = false; @@ -2128,6 +2130,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(attr) => attr.level.is_stable(), None => true, }) + .filter(|info| { + // Static candidates are already implemented, and known not to work + // Do not suggest them again + static_candidates.iter().all(|sc| match *sc { + CandidateSource::Trait(def_id) => def_id != info.def_id, + CandidateSource::Impl(def_id) => { + self.tcx.trait_id_of_impl(def_id) != Some(info.def_id) + } + }) + }) .filter(|info| { // We approximate the coherence rules to only suggest // traits that are legal to implement by requiring that From 8cf9ad634b049af8b9f442e5b31bc6a85c3a3392 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 25 Oct 2022 15:28:02 -0700 Subject: [PATCH 2/2] diagnostics: add test case for issue 102354 --- src/test/ui/suggestions/issue-102354.rs | 10 +++++++++ src/test/ui/suggestions/issue-102354.stderr | 24 +++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/ui/suggestions/issue-102354.rs create mode 100644 src/test/ui/suggestions/issue-102354.stderr diff --git a/src/test/ui/suggestions/issue-102354.rs b/src/test/ui/suggestions/issue-102354.rs new file mode 100644 index 00000000000..f881feb0060 --- /dev/null +++ b/src/test/ui/suggestions/issue-102354.rs @@ -0,0 +1,10 @@ +trait Trait { + fn func() {} +} + +impl Trait for i32 {} + +fn main() { + let x: i32 = 123; + x.func(); //~ERROR no method +} diff --git a/src/test/ui/suggestions/issue-102354.stderr b/src/test/ui/suggestions/issue-102354.stderr new file mode 100644 index 00000000000..4f76c5f2e75 --- /dev/null +++ b/src/test/ui/suggestions/issue-102354.stderr @@ -0,0 +1,24 @@ +error[E0599]: no method named `func` found for type `i32` in the current scope + --> $DIR/issue-102354.rs:9:7 + | +LL | x.func(); + | ^^^^ this is an associated function, not a method + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in the trait `Trait` + --> $DIR/issue-102354.rs:2:5 + | +LL | fn func() {} + | ^^^^^^^^^ +help: use associated function syntax instead + | +LL | i32::func(); + | ~~~~~~~~~ +help: disambiguate the associated function for the candidate + | +LL | ::func(x); + | ~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`.