mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Rollup merge of #103550 - notriddle:notriddle/no-suggest-static-candidates, r=wesleywiser
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. Partial fix for #102354
This commit is contained in:
commit
f541ad9165
@ -106,7 +106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
let report_candidates = |span: Span,
|
let report_candidates = |span: Span,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
mut sources: Vec<CandidateSource>,
|
sources: &mut Vec<CandidateSource>,
|
||||||
sugg_span: Span| {
|
sugg_span: Span| {
|
||||||
sources.sort();
|
sources.sort();
|
||||||
sources.dedup();
|
sources.dedup();
|
||||||
@ -248,7 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
match error {
|
match error {
|
||||||
MethodError::NoMatch(NoMatchData {
|
MethodError::NoMatch(NoMatchData {
|
||||||
static_candidates: static_sources,
|
static_candidates: mut static_sources,
|
||||||
unsatisfied_predicates,
|
unsatisfied_predicates,
|
||||||
out_of_scope_traits,
|
out_of_scope_traits,
|
||||||
lev_candidate,
|
lev_candidate,
|
||||||
@ -422,9 +422,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.help(&format!("try with `{}::{}`", ty_str, item_name,));
|
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 {
|
} 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![];
|
let mut bound_spans = vec![];
|
||||||
@ -1007,6 +1007,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
source,
|
source,
|
||||||
out_of_scope_traits,
|
out_of_scope_traits,
|
||||||
&unsatisfied_predicates,
|
&unsatisfied_predicates,
|
||||||
|
&static_sources,
|
||||||
unsatisfied_bounds,
|
unsatisfied_bounds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1079,7 +1080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
return Some(err);
|
return Some(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodError::Ambiguity(sources) => {
|
MethodError::Ambiguity(mut sources) => {
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
self.sess(),
|
self.sess(),
|
||||||
item_name.span,
|
item_name.span,
|
||||||
@ -1088,7 +1089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
err.span_label(item_name.span, format!("multiple `{}` found", item_name));
|
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();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2015,6 +2016,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Option<ty::Predicate<'tcx>>,
|
Option<ty::Predicate<'tcx>>,
|
||||||
Option<ObligationCause<'tcx>>,
|
Option<ObligationCause<'tcx>>,
|
||||||
)],
|
)],
|
||||||
|
static_candidates: &[CandidateSource],
|
||||||
unsatisfied_bounds: bool,
|
unsatisfied_bounds: bool,
|
||||||
) {
|
) {
|
||||||
let mut alt_rcvr_sugg = false;
|
let mut alt_rcvr_sugg = false;
|
||||||
@ -2128,6 +2130,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Some(attr) => attr.level.is_stable(),
|
Some(attr) => attr.level.is_stable(),
|
||||||
None => true,
|
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| {
|
.filter(|info| {
|
||||||
// We approximate the coherence rules to only suggest
|
// We approximate the coherence rules to only suggest
|
||||||
// traits that are legal to implement by requiring that
|
// traits that are legal to implement by requiring that
|
||||||
|
10
src/test/ui/suggestions/issue-102354.rs
Normal file
10
src/test/ui/suggestions/issue-102354.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
trait Trait {
|
||||||
|
fn func() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for i32 {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: i32 = 123;
|
||||||
|
x.func(); //~ERROR no method
|
||||||
|
}
|
24
src/test/ui/suggestions/issue-102354.stderr
Normal file
24
src/test/ui/suggestions/issue-102354.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user