Suggest associated method on deref types
This commit is contained in:
parent
0421444f8f
commit
12a4952369
@ -16,8 +16,8 @@
|
||||
use rustc_middle::traits::util::supertraits;
|
||||
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::print::with_crate_prefix;
|
||||
use rustc_middle::ty::ToPolyTraitRef;
|
||||
use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, Span};
|
||||
@ -30,7 +30,7 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::iter;
|
||||
|
||||
use super::probe::{Mode, ProbeScope};
|
||||
use super::probe::{IsSuggestion, Mode, ProbeScope};
|
||||
use super::{CandidateSource, MethodError, NoMatchData};
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@ -1069,6 +1069,8 @@ trait bound{s}",
|
||||
}
|
||||
}
|
||||
|
||||
self.check_for_deref_method(&mut err, source, rcvr_ty, item_name);
|
||||
|
||||
return Some(err);
|
||||
}
|
||||
|
||||
@ -1651,6 +1653,62 @@ fn suggest_derive(
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_deref_method(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
self_source: SelfSource<'tcx>,
|
||||
rcvr_ty: Ty<'tcx>,
|
||||
item_name: Ident,
|
||||
) {
|
||||
let SelfSource::QPath(ty) = self_source else { return; };
|
||||
for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) {
|
||||
if let Ok(pick) = self.probe_for_name(
|
||||
ty.span,
|
||||
Mode::Path,
|
||||
item_name,
|
||||
IsSuggestion(true),
|
||||
deref_ty,
|
||||
ty.hir_id,
|
||||
ProbeScope::TraitsInScope,
|
||||
) {
|
||||
if deref_ty.is_suggestable(self.tcx, true)
|
||||
// If this method receives `&self`, then the provided
|
||||
// argument _should_ coerce, so it's valid to suggest
|
||||
// just changing the path.
|
||||
&& pick.item.fn_has_self_parameter
|
||||
&& let Some(self_ty) =
|
||||
self.tcx.fn_sig(pick.item.def_id).inputs().skip_binder().get(0)
|
||||
&& self_ty.is_ref()
|
||||
{
|
||||
let suggested_path = match deref_ty.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::Adt(_, _)
|
||||
| ty::Str
|
||||
| ty::Projection(_)
|
||||
| ty::Param(_) => format!("{deref_ty}"),
|
||||
_ => format!("<{deref_ty}>"),
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
ty.span,
|
||||
format!("the function `{item_name}` is implemented on `{deref_ty}`"),
|
||||
suggested_path,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_note(
|
||||
ty.span,
|
||||
format!("the function `{item_name}` is implemented on `{deref_ty}`"),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Print out the type for use in value namespace.
|
||||
fn ty_to_value_string(&self, ty: Ty<'tcx>) -> String {
|
||||
match ty.kind() {
|
||||
|
6
src/test/ui/suggestions/deref-path-method.rs
Normal file
6
src/test/ui/suggestions/deref-path-method.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
let vec = Vec::new();
|
||||
Vec::contains(&vec, &0);
|
||||
//~^ ERROR no function or associated item named `contains` found for struct `Vec<_, _>` in the current scope
|
||||
//~| HELP the function `contains` is implemented on `[_]`
|
||||
}
|
14
src/test/ui/suggestions/deref-path-method.stderr
Normal file
14
src/test/ui/suggestions/deref-path-method.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0599]: no function or associated item named `contains` found for struct `Vec<_, _>` in the current scope
|
||||
--> $DIR/deref-path-method.rs:3:10
|
||||
|
|
||||
LL | Vec::contains(&vec, &0);
|
||||
| ^^^^^^^^ function or associated item not found in `Vec<_, _>`
|
||||
|
|
||||
help: the function `contains` is implemented on `[_]`
|
||||
|
|
||||
LL | <[_]>::contains(&vec, &0);
|
||||
| ~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user