Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

diagnostics: do not suggest static candidates as traits to import #103550

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let report_candidates = |span: Span,
err: &mut Diagnostic,
mut sources: Vec<CandidateSource>,
sources: &mut Vec<CandidateSource>,
sugg_span: Span| {
sources.sort();
sources.dedup();
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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![];
Expand Down Expand Up @@ -1007,6 +1007,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
source,
out_of_scope_traits,
&unsatisfied_predicates,
&static_sources,
unsatisfied_bounds,
);
}
Expand Down Expand Up @@ -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,
Expand All @@ -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();
}

Expand Down Expand Up @@ -2015,6 +2016,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>,
)],
static_candidates: &[CandidateSource],
unsatisfied_bounds: bool,
) {
let mut alt_rcvr_sugg = false;
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/suggestions/issue-102354.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
trait Trait {
fn func() {}
}

impl Trait for i32 {}

fn main() {
let x: i32 = 123;
x.func(); //~ERROR no method
}
24 changes: 24 additions & 0 deletions src/test/ui/suggestions/issue-102354.stderr
Original file line number Diff line number Diff line change
@@ -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 | <i32 as Trait>::func(x);
| ~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.