Rollup merge of #104394 - oli-obk:suggest_method_call, r=lcnr

various cleanups to try to reduce the use of spans inside method resolution

definitely review commit by commit.
This commit is contained in:
Matthias Krüger 2022-11-16 15:39:46 +01:00 committed by GitHub
commit 163a7090b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 126 additions and 123 deletions

View File

@ -504,7 +504,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// method lookup. // method lookup.
let Ok(pick) = self let Ok(pick) = self
.probe_for_name( .probe_for_name(
call_expr.span,
Mode::MethodCall, Mode::MethodCall,
segment.ident, segment.ident,
IsSuggestion(true), IsSuggestion(true),

View File

@ -93,17 +93,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
call_expr_id: hir::HirId, call_expr_id: hir::HirId,
allow_private: bool, allow_private: bool,
) -> bool { ) -> bool {
let mode = probe::Mode::MethodCall;
match self.probe_for_name( match self.probe_for_name(
method_name.span, probe::Mode::MethodCall,
mode,
method_name, method_name,
IsSuggestion(false), IsSuggestion(false),
self_ty, self_ty,
call_expr_id, call_expr_id,
ProbeScope::TraitsInScope, ProbeScope::TraitsInScope,
) { ) {
Ok(..) => true, Ok(pick) => {
pick.maybe_emit_unstable_name_collision_hint(
self.tcx,
method_name.span,
call_expr_id,
);
true
}
Err(NoMatch(..)) => false, Err(NoMatch(..)) => false,
Err(Ambiguity(..)) => true, Err(Ambiguity(..)) => true,
Err(PrivateMatch(..)) => allow_private, Err(PrivateMatch(..)) => allow_private,
@ -125,10 +130,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) { ) {
let params = self let params = self
.probe_for_name( .probe_for_name(
method_name.span,
probe::Mode::MethodCall, probe::Mode::MethodCall,
method_name, method_name,
IsSuggestion(false), IsSuggestion(true),
self_ty, self_ty,
call_expr.hir_id, call_expr.hir_id,
ProbeScope::TraitsInScope, ProbeScope::TraitsInScope,
@ -175,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
args: &'tcx [hir::Expr<'tcx>], args: &'tcx [hir::Expr<'tcx>],
) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> { ) -> Result<MethodCallee<'tcx>, MethodError<'tcx>> {
let pick = let pick =
self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?;
self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick, args); self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick, args);
@ -200,13 +204,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.mk_ref(*region, ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() }); .mk_ref(*region, ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() });
// We probe again to see if there might be a borrow mutability discrepancy. // We probe again to see if there might be a borrow mutability discrepancy.
match self.lookup_probe( match self.lookup_probe(
span,
segment.ident, segment.ident,
trait_type, trait_type,
call_expr, call_expr,
ProbeScope::TraitsInScope, ProbeScope::TraitsInScope,
) { ) {
Ok(ref new_pick) if *new_pick != pick => { Ok(ref new_pick) if pick.differs_from(new_pick) => {
needs_mut = true; needs_mut = true;
} }
_ => {} _ => {}
@ -214,15 +217,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
// We probe again, taking all traits into account (not only those in scope). // We probe again, taking all traits into account (not only those in scope).
let mut candidates = match self.lookup_probe( let mut candidates =
span, match self.lookup_probe(segment.ident, self_ty, call_expr, ProbeScope::AllTraits) {
segment.ident,
self_ty,
call_expr,
ProbeScope::AllTraits,
) {
// If we find a different result the caller probably forgot to import a trait. // If we find a different result the caller probably forgot to import a trait.
Ok(ref new_pick) if *new_pick != pick => vec![new_pick.item.container_id(self.tcx)], Ok(ref new_pick) if pick.differs_from(new_pick) => {
vec![new_pick.item.container_id(self.tcx)]
}
Err(Ambiguity(ref sources)) => sources Err(Ambiguity(ref sources)) => sources
.iter() .iter()
.filter_map(|source| { .filter_map(|source| {
@ -247,23 +247,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self, call_expr))] #[instrument(level = "debug", skip(self, call_expr))]
pub fn lookup_probe( pub fn lookup_probe(
&self, &self,
span: Span,
method_name: Ident, method_name: Ident,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
call_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>,
scope: ProbeScope, scope: ProbeScope,
) -> probe::PickResult<'tcx> { ) -> probe::PickResult<'tcx> {
let mode = probe::Mode::MethodCall; let pick = self.probe_for_name(
let self_ty = self.resolve_vars_if_possible(self_ty); probe::Mode::MethodCall,
self.probe_for_name(
span,
mode,
method_name, method_name,
IsSuggestion(false), IsSuggestion(false),
self_ty, self_ty,
call_expr.hir_id, call_expr.hir_id,
scope, scope,
) )?;
pick.maybe_emit_unstable_name_collision_hint(self.tcx, method_name.span, call_expr.hir_id);
Ok(pick)
} }
pub(super) fn obligation_for_method( pub(super) fn obligation_for_method(
@ -587,7 +585,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
let pick = self.probe_for_name( let pick = self.probe_for_name(
span,
probe::Mode::Path, probe::Mode::Path,
method_name, method_name,
IsSuggestion(false), IsSuggestion(false),
@ -596,6 +593,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ProbeScope::TraitsInScope, ProbeScope::TraitsInScope,
)?; )?;
pick.maybe_emit_unstable_name_collision_hint(self.tcx, span, expr_id);
self.lint_fully_qualified_call_from_2018( self.lint_fully_qualified_call_from_2018(
span, span,
method_name, method_name,

View File

@ -17,6 +17,7 @@ use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::middle::stability; use rustc_middle::middle::stability;
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::AssocItem;
use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable};
use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_middle::ty::{InternalSubsts, SubstsRef};
@ -83,8 +84,6 @@ struct ProbeContext<'a, 'tcx> {
unsatisfied_predicates: unsatisfied_predicates:
Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>, Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
is_suggestion: IsSuggestion,
scope_expr_id: hir::HirId, scope_expr_id: hir::HirId,
} }
@ -193,7 +192,7 @@ impl AutorefOrPtrAdjustment {
} }
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, Clone)]
pub struct Pick<'tcx> { pub struct Pick<'tcx> {
pub item: ty::AssocItem, pub item: ty::AssocItem,
pub kind: PickKind<'tcx>, pub kind: PickKind<'tcx>,
@ -209,6 +208,9 @@ pub struct Pick<'tcx> {
/// `*mut T`, convert it to `*const T`. /// `*mut T`, convert it to `*const T`.
pub autoref_or_ptr_adjustment: Option<AutorefOrPtrAdjustment>, pub autoref_or_ptr_adjustment: Option<AutorefOrPtrAdjustment>,
pub self_ty: Ty<'tcx>, pub self_ty: Ty<'tcx>,
/// Unstable candidates alongside the stable ones.
unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>,
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -298,7 +300,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub fn probe_for_name( pub fn probe_for_name(
&self, &self,
span: Span,
mode: Mode, mode: Mode,
item_name: Ident, item_name: Ident,
is_suggestion: IsSuggestion, is_suggestion: IsSuggestion,
@ -307,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
scope: ProbeScope, scope: ProbeScope,
) -> PickResult<'tcx> { ) -> PickResult<'tcx> {
self.probe_op( self.probe_op(
span, item_name.span,
mode, mode,
Some(item_name), Some(item_name),
None, None,
@ -446,7 +447,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return_type, return_type,
orig_values, orig_values,
steps.steps, steps.steps,
is_suggestion,
scope_expr_id, scope_expr_id,
); );
@ -541,7 +541,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
return_type: Option<Ty<'tcx>>, return_type: Option<Ty<'tcx>>,
orig_steps_var_values: OriginalQueryValues<'tcx>, orig_steps_var_values: OriginalQueryValues<'tcx>,
steps: &'tcx [CandidateStep<'tcx>], steps: &'tcx [CandidateStep<'tcx>],
is_suggestion: IsSuggestion,
scope_expr_id: hir::HirId, scope_expr_id: hir::HirId,
) -> ProbeContext<'a, 'tcx> { ) -> ProbeContext<'a, 'tcx> {
ProbeContext { ProbeContext {
@ -559,7 +558,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
allow_similar_names: false, allow_similar_names: false,
private_candidate: None, private_candidate: None,
unsatisfied_predicates: Vec::new(), unsatisfied_predicates: Vec::new(),
is_suggestion,
scope_expr_id, scope_expr_id,
} }
} }
@ -881,7 +879,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
} }
} }
pub fn matches_return_type( fn matches_return_type(
&self, &self,
method: &ty::AssocItem, method: &ty::AssocItem,
self_ty: Option<Ty<'tcx>>, self_ty: Option<Ty<'tcx>>,
@ -1052,27 +1050,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
} }
fn pick_core(&mut self) -> Option<PickResult<'tcx>> { fn pick_core(&mut self) -> Option<PickResult<'tcx>> {
let mut unstable_candidates = Vec::new(); let pick = self.pick_all_method(Some(&mut vec![]));
let pick = self.pick_all_method(Some(&mut unstable_candidates));
// In this case unstable picking is done by `pick_method`. // In this case unstable picking is done by `pick_method`.
if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable { if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable {
return pick; return pick;
} }
match pick { if pick.is_none() {
// Emit a lint if there are unstable candidates alongside the stable ones. return self.pick_all_method(None);
// }
// We suppress warning if we're picking the method only because it is a
// suggestion.
Some(Ok(ref p)) if !self.is_suggestion.0 && !unstable_candidates.is_empty() => {
self.emit_unstable_name_collision_hint(p, &unstable_candidates);
pick pick
} }
Some(_) => pick,
None => self.pick_all_method(None),
}
}
fn pick_all_method( fn pick_all_method(
&mut self, &mut self,
@ -1216,7 +1205,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty)); debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty));
let mut possibly_unsatisfied_predicates = Vec::new(); let mut possibly_unsatisfied_predicates = Vec::new();
let mut unstable_candidates = Vec::new();
for (kind, candidates) in for (kind, candidates) in
&[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)] &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
@ -1226,26 +1214,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self_ty, self_ty,
candidates.iter(), candidates.iter(),
&mut possibly_unsatisfied_predicates, &mut possibly_unsatisfied_predicates,
Some(&mut unstable_candidates), Some(&mut vec![]),
); );
if let Some(pick) = res { if res.is_some() {
if !self.is_suggestion.0 && !unstable_candidates.is_empty() { return res;
if let Ok(p) = &pick {
// Emit a lint if there are unstable candidates alongside the stable ones.
//
// We suppress warning if we're picking the method only because it is a
// suggestion.
self.emit_unstable_name_collision_hint(p, &unstable_candidates);
}
}
return Some(pick);
} }
} }
debug!("searching unstable candidates"); debug!("searching unstable candidates");
let res = self.consider_candidates( let res = self.consider_candidates(
self_ty, self_ty,
unstable_candidates.iter().map(|(c, _)| c), self.inherent_candidates.iter().chain(&self.extension_candidates),
&mut possibly_unsatisfied_predicates, &mut possibly_unsatisfied_predicates,
None, None,
); );
@ -1300,7 +1279,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
Option<ty::Predicate<'tcx>>, Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>, Option<ObligationCause<'tcx>>,
)>, )>,
unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
) -> Option<PickResult<'tcx>> ) -> Option<PickResult<'tcx>>
where where
ProbesIter: Iterator<Item = &'b Candidate<'tcx>> + Clone, ProbesIter: Iterator<Item = &'b Candidate<'tcx>> + Clone,
@ -1324,7 +1303,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
} }
} }
if let Some(uc) = unstable_candidates { if let Some(uc) = &mut unstable_candidates {
applicable_candidates.retain(|&(p, _)| { applicable_candidates.retain(|&(p, _)| {
if let stability::EvalResult::Deny { feature, .. } = if let stability::EvalResult::Deny { feature, .. } =
self.tcx.eval_stability(p.item.def_id, None, self.span, None) self.tcx.eval_stability(p.item.def_id, None, self.span, None)
@ -1343,30 +1322,63 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
applicable_candidates.pop().map(|(probe, status)| { applicable_candidates.pop().map(|(probe, status)| {
if status == ProbeResult::Match { if status == ProbeResult::Match {
Ok(probe.to_unadjusted_pick(self_ty)) Ok(probe
.to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default()))
} else { } else {
Err(MethodError::BadReturnType) Err(MethodError::BadReturnType)
} }
}) })
} }
}
fn emit_unstable_name_collision_hint( impl<'tcx> Pick<'tcx> {
/// In case there were unstable name collisions, emit them as a lint.
/// Checks whether two picks do not refer to the same trait item for the same `Self` type.
/// Only useful for comparisons of picks in order to improve diagnostics.
/// Do not use for type checking.
pub fn differs_from(&self, other: &Self) -> bool {
let Self {
item:
AssocItem {
def_id,
name: _,
kind: _,
container: _,
trait_item_def_id: _,
fn_has_self_parameter: _,
},
kind: _,
import_ids: _,
autoderefs: _,
autoref_or_ptr_adjustment: _,
self_ty,
unstable_candidates: _,
} = *self;
self_ty != other.self_ty || def_id != other.item.def_id
}
/// In case there were unstable name collisions, emit them as a lint.
pub fn maybe_emit_unstable_name_collision_hint(
&self, &self,
stable_pick: &Pick<'_>, tcx: TyCtxt<'tcx>,
unstable_candidates: &[(Candidate<'tcx>, Symbol)], span: Span,
scope_expr_id: hir::HirId,
) { ) {
let def_kind = stable_pick.item.kind.as_def_kind(); if self.unstable_candidates.is_empty() {
self.tcx.struct_span_lint_hir( return;
}
let def_kind = self.item.kind.as_def_kind();
tcx.struct_span_lint_hir(
lint::builtin::UNSTABLE_NAME_COLLISIONS, lint::builtin::UNSTABLE_NAME_COLLISIONS,
self.scope_expr_id, scope_expr_id,
self.span, span,
format!( format!(
"{} {} with this name may be added to the standard library in the future", "{} {} with this name may be added to the standard library in the future",
def_kind.article(), def_kind.article(),
def_kind.descr(stable_pick.item.def_id), def_kind.descr(self.item.def_id),
), ),
|lint| { |lint| {
match (stable_pick.item.kind, stable_pick.item.container) { match (self.item.kind, self.item.container) {
(ty::AssocKind::Fn, _) => { (ty::AssocKind::Fn, _) => {
// FIXME: This should be a `span_suggestion` instead of `help` // FIXME: This should be a `span_suggestion` instead of `help`
// However `self.span` only // However `self.span` only
@ -1375,31 +1387,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
lint.help(&format!( lint.help(&format!(
"call with fully qualified syntax `{}(...)` to keep using the current \ "call with fully qualified syntax `{}(...)` to keep using the current \
method", method",
self.tcx.def_path_str(stable_pick.item.def_id), tcx.def_path_str(self.item.def_id),
)); ));
} }
(ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
let def_id = stable_pick.item.container_id(self.tcx); let def_id = self.item.container_id(tcx);
lint.span_suggestion( lint.span_suggestion(
self.span, span,
"use the fully qualified path to the associated const", "use the fully qualified path to the associated const",
format!( format!(
"<{} as {}>::{}", "<{} as {}>::{}",
stable_pick.self_ty, self.self_ty,
self.tcx.def_path_str(def_id), tcx.def_path_str(def_id),
stable_pick.item.name self.item.name
), ),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} }
_ => {} _ => {}
} }
if self.tcx.sess.is_nightly_build() { if tcx.sess.is_nightly_build() {
for (candidate, feature) in unstable_candidates { for (candidate, feature) in &self.unstable_candidates {
lint.help(&format!( lint.help(&format!(
"add `#![feature({})]` to the crate attributes to enable `{}`", "add `#![feature({})]` to the crate attributes to enable `{}`",
feature, feature,
self.tcx.def_path_str(candidate.item.def_id), tcx.def_path_str(candidate.item.def_id),
)); ));
} }
} }
@ -1408,7 +1420,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}, },
); );
} }
}
impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
fn select_trait_candidate( fn select_trait_candidate(
&self, &self,
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
@ -1667,6 +1681,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
autoderefs: 0, autoderefs: 0,
autoref_or_ptr_adjustment: None, autoref_or_ptr_adjustment: None,
self_ty, self_ty,
unstable_candidates: vec![],
}) })
} }
@ -1686,7 +1701,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.return_type, self.return_type,
self.orig_steps_var_values.clone(), self.orig_steps_var_values.clone(),
steps, steps,
IsSuggestion(true),
self.scope_expr_id, self.scope_expr_id,
); );
pcx.allow_similar_names = true; pcx.allow_similar_names = true;
@ -1894,7 +1908,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
} }
impl<'tcx> Candidate<'tcx> { impl<'tcx> Candidate<'tcx> {
fn to_unadjusted_pick(&self, self_ty: Ty<'tcx>) -> Pick<'tcx> { fn to_unadjusted_pick(
&self,
self_ty: Ty<'tcx>,
unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>,
) -> Pick<'tcx> {
Pick { Pick {
item: self.item, item: self.item,
kind: match self.kind { kind: match self.kind {
@ -1919,6 +1937,7 @@ impl<'tcx> Candidate<'tcx> {
autoderefs: 0, autoderefs: 0,
autoref_or_ptr_adjustment: None, autoref_or_ptr_adjustment: None,
self_ty, self_ty,
unstable_candidates,
} }
} }
} }

View File

@ -376,7 +376,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.hir() .hir()
.expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id)); .expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id));
let probe = self.lookup_probe( let probe = self.lookup_probe(
span,
item_name, item_name,
output_ty, output_ty,
call_expr, call_expr,
@ -914,7 +913,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
} }
self.check_for_inner_self(&mut err, source, span, rcvr_ty, item_name); self.check_for_inner_self(&mut err, source, rcvr_ty, item_name);
bound_spans.sort(); bound_spans.sort();
bound_spans.dedup(); bound_spans.dedup();
@ -1321,7 +1320,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.bound_type_of(range_def_id).subst(self.tcx, &[actual.into()]); self.tcx.bound_type_of(range_def_id).subst(self.tcx, &[actual.into()]);
let pick = self.probe_for_name( let pick = self.probe_for_name(
span,
Mode::MethodCall, Mode::MethodCall,
item_name, item_name,
IsSuggestion(true), IsSuggestion(true),
@ -1500,7 +1498,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span, span,
&|_, field_ty| { &|_, field_ty| {
self.lookup_probe( self.lookup_probe(
span,
item_name, item_name,
field_ty, field_ty,
call_expr, call_expr,
@ -1548,7 +1545,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
err: &mut Diagnostic, err: &mut Diagnostic,
source: SelfSource<'tcx>, source: SelfSource<'tcx>,
span: Span,
actual: Ty<'tcx>, actual: Ty<'tcx>,
item_name: Ident, item_name: Ident,
) { ) {
@ -1571,13 +1567,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return None; return None;
} }
self.lookup_probe( self.lookup_probe(item_name, field_ty, call_expr, ProbeScope::TraitsInScope)
span,
item_name,
field_ty,
call_expr,
ProbeScope::TraitsInScope,
)
.ok() .ok()
.map(|pick| (variant, field, pick)) .map(|pick| (variant, field, pick))
}) })
@ -1644,7 +1634,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let [first] = ***substs else { return; }; let [first] = ***substs else { return; };
let ty::GenericArgKind::Type(ty) = first.unpack() else { return; }; let ty::GenericArgKind::Type(ty) = first.unpack() else { return; };
let Ok(pick) = self.lookup_probe( let Ok(pick) = self.lookup_probe(
span,
item_name, item_name,
ty, ty,
call_expr, call_expr,
@ -1899,7 +1888,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let SelfSource::QPath(ty) = self_source else { return; }; let SelfSource::QPath(ty) = self_source else { return; };
for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) { for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) {
if let Ok(pick) = self.probe_for_name( if let Ok(pick) = self.probe_for_name(
ty.span,
Mode::Path, Mode::Path,
item_name, item_name,
IsSuggestion(true), IsSuggestion(true),
@ -2107,7 +2095,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "), (self.tcx.mk_mut_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&mut "),
(self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"), (self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, rcvr_ty), "&"),
] { ] {
match self.lookup_probe(span, item_name, *rcvr_ty, rcvr, ProbeScope::AllTraits) { match self.lookup_probe(item_name, *rcvr_ty, rcvr, ProbeScope::AllTraits) {
Ok(pick) => { Ok(pick) => {
// If the method is defined for the receiver we have, it likely wasn't `use`d. // If the method is defined for the receiver we have, it likely wasn't `use`d.
// We point at the method, but we just skip the rest of the check for arbitrary // We point at the method, but we just skip the rest of the check for arbitrary
@ -2141,7 +2129,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
] { ] {
if let Some(new_rcvr_t) = *rcvr_ty if let Some(new_rcvr_t) = *rcvr_ty
&& let Ok(pick) = self.lookup_probe( && let Ok(pick) = self.lookup_probe(
span,
item_name, item_name,
new_rcvr_t, new_rcvr_t,
rcvr, rcvr,
@ -2522,7 +2509,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: method_name.span, span: method_name.span,
}; };
let probe = self.lookup_probe( let probe = self.lookup_probe(
expr.span,
new_name, new_name,
self_ty, self_ty,
self_expr, self_expr,