Skip to content

Commit

Permalink
Rollup merge of #100302 - compiler-errors:deref-path-methods, r=jackh726
Browse files Browse the repository at this point in the history
Suggest associated method on deref types when path syntax method fails

Fixes #100278
  • Loading branch information
matthiaskrgr authored Sep 3, 2022
2 parents 84f0c3f + 12a4952 commit bd9750f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 2 deletions.
62 changes: 60 additions & 2 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
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};
Expand All @@ -30,7 +30,7 @@ use rustc_trait_selection::traits::{
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> {
Expand Down Expand Up @@ -1069,6 +1069,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

self.check_for_deref_method(&mut err, source, rcvr_ty, item_name);

return Some(err);
}

Expand Down Expand Up @@ -1651,6 +1653,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

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() {
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/suggestions/deref-path-method.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions src/test/ui/suggestions/deref-path-method.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit bd9750f

Please sign in to comment.