]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_hir_typeck/src/method/probe.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / compiler / rustc_hir_typeck / src / method / probe.rs
CommitLineData
dfeec247 1use super::suggest;
04454e1e 2use super::CandidateSource;
c34b1796 3use super::MethodError;
62682a34 4use super::NoMatchData;
1a4d82fc 5
1b1a35ee 6use crate::errors::MethodCallOnUnknownType;
2b03887a 7use crate::FnCtxt;
dfeec247 8use rustc_data_structures::fx::FxHashSet;
6a06907d 9use rustc_errors::Applicability;
dfeec247 10use rustc_hir as hir;
2b03887a 11use rustc_hir::def::DefKind;
9c376795 12use rustc_hir_analysis::autoderef::{self, Autoderef};
74b04a01
XL
13use rustc_infer::infer::canonical::OriginalQueryValues;
14use rustc_infer::infer::canonical::{Canonical, QueryResponse};
15use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
74b04a01 16use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
5e7ed085 17use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
ba9703b0 18use rustc_middle::middle::stability;
5e7ed085 19use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
487cf647 20use rustc_middle::ty::AssocItem;
ba9703b0 21use rustc_middle::ty::GenericParamDefKind;
487cf647
FG
22use rustc_middle::ty::ToPredicate;
23use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitable};
2b03887a 24use rustc_middle::ty::{InternalSubsts, SubstsRef};
ba9703b0 25use rustc_session::lint;
2b03887a 26use rustc_span::def_id::DefId;
f035d41b 27use rustc_span::def_id::LocalDefId;
04454e1e
FG
28use rustc_span::lev_distance::{
29 find_best_match_for_name_with_substrings, lev_distance_with_substrings,
30};
31use rustc_span::symbol::sym;
f9f354fc 32use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
ba9703b0
XL
33use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
34use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy;
35use rustc_trait_selection::traits::query::method_autoderef::{
36 CandidateStep, MethodAutoderefStepsResult,
37};
38use rustc_trait_selection::traits::query::CanonicalTyGoal;
487cf647 39use rustc_trait_selection::traits::NormalizeExt;
ba9703b0 40use rustc_trait_selection::traits::{self, ObligationCause};
9c376795 41use std::cell::RefCell;
dfeec247 42use std::cmp::max;
a1dfa0c6 43use std::iter;
a7813a04 44use std::ops::Deref;
60c5eb7d 45
48663c56
XL
46use smallvec::{smallvec, SmallVec};
47
1a4d82fc 48use self::CandidateKind::*;
1a4d82fc
JJ
49pub use self::PickKind::*;
50
32a655c1 51/// Boolean flag used to indicate if this search is for a suggestion
0731742a 52/// or not. If true, we can allow ambiguity and so forth.
5869c6ff 53#[derive(Clone, Copy, Debug)]
32a655c1
SL
54pub struct IsSuggestion(pub bool);
55
dc9dc135
XL
56struct ProbeContext<'a, 'tcx> {
57 fcx: &'a FnCtxt<'a, 'tcx>,
1a4d82fc 58 span: Span,
c34b1796 59 mode: Mode,
f9f354fc 60 method_name: Option<Ident>,
ea8adc8c 61 return_type: Option<Ty<'tcx>>,
0731742a
XL
62
63 /// This is the OriginalQueryValues for the steps queries
64 /// that are answered in steps.
9c376795 65 orig_steps_var_values: &'a OriginalQueryValues<'tcx>,
5099ac24 66 steps: &'tcx [CandidateStep<'tcx>],
0731742a 67
1a4d82fc
JJ
68 inherent_candidates: Vec<Candidate<'tcx>>,
69 extension_candidates: Vec<Candidate<'tcx>>,
476ff2be 70 impl_dups: FxHashSet<DefId>,
62682a34 71
ea8adc8c 72 /// When probing for names, include names that are close to the
9c376795 73 /// requested name (by Levenshtein distance)
ea8adc8c
XL
74 allow_similar_names: bool,
75
54a0048b 76 /// Some(candidate) if there is a private candidate
48663c56 77 private_candidate: Option<(DefKind, DefId)>,
54a0048b 78
9c376795
FG
79 /// Collects near misses when the candidate functions are missing a `self` keyword and is only
80 /// used for error reporting
81 static_candidates: RefCell<Vec<CandidateSource>>,
82
62682a34
SL
83 /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
84 /// for error reporting
9c376795 85 unsatisfied_predicates: RefCell<
3c0e092e 86 Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>,
9c376795 87 >,
0531ce1d 88
cdc7bbd5 89 scope_expr_id: hir::HirId,
1a4d82fc
JJ
90}
91
dc9dc135
XL
92impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> {
93 type Target = FnCtxt<'a, 'tcx>;
a7813a04 94 fn deref(&self) -> &Self::Target {
c295e0f8 95 self.fcx
a7813a04
XL
96 }
97}
98
3c0e092e 99#[derive(Debug, Clone)]
9c376795 100pub(crate) struct Candidate<'tcx> {
0731742a 101 // Candidates are (I'm not quite sure, but they are mostly) basically
dc9dc135 102 // some metadata on top of a `ty::AssocItem` (without substs).
0731742a
XL
103 //
104 // However, method probing wants to be able to evaluate the predicates
105 // for a function with the substs applied - for example, if a function
106 // has `where Self: Sized`, we don't want to consider it unless `Self`
107 // is actually `Sized`, and similarly, return-type suggestions want
108 // to consider the "actual" return type.
109 //
110 // The way this is handled is through `xform_self_ty`. It contains
111 // the receiver type of this candidate, but `xform_self_ty`,
112 // `xform_ret_ty` and `kind` (which contains the predicates) have the
113 // generic parameters of this candidate substituted with the *same set*
114 // of inference variables, which acts as some weird sort of "query".
115 //
116 // When we check out a candidate, we require `xform_self_ty` to be
117 // a subtype of the passed-in self-type, and this equates the type
118 // variables in the rest of the fields.
119 //
120 // For example, if we have this candidate:
121 // ```
122 // trait Foo {
123 // fn foo(&self) where Self: Sized;
124 // }
125 // ```
126 //
127 // Then `xform_self_ty` will be `&'erased ?X` and `kind` will contain
128 // the predicate `?X: Sized`, so if we are evaluating `Foo` for a
129 // the receiver `&T`, we'll do the subtyping which will make `?X`
130 // get the right value, then when we evaluate the predicate we'll check
131 // if `T: Sized`.
1a4d82fc 132 xform_self_ty: Ty<'tcx>,
ea8adc8c 133 xform_ret_ty: Option<Ty<'tcx>>,
9c376795
FG
134 pub(crate) item: ty::AssocItem,
135 pub(crate) kind: CandidateKind<'tcx>,
136 pub(crate) import_ids: SmallVec<[LocalDefId; 1]>,
1a4d82fc
JJ
137}
138
3c0e092e 139#[derive(Debug, Clone)]
9c376795 140pub(crate) enum CandidateKind<'tcx> {
dfeec247
XL
141 InherentImplCandidate(
142 SubstsRef<'tcx>,
143 // Normalize obligations
144 Vec<traits::PredicateObligation<'tcx>>,
145 ),
c1a9b12d 146 ObjectCandidate,
ea8adc8c 147 TraitCandidate(ty::TraitRef<'tcx>),
dfeec247
XL
148 WhereClauseCandidate(
149 // Trait
150 ty::PolyTraitRef<'tcx>,
151 ),
1a4d82fc
JJ
152}
153
ea8adc8c
XL
154#[derive(Debug, PartialEq, Eq, Copy, Clone)]
155enum ProbeResult {
156 NoMatch,
157 BadReturnType,
158 Match,
159}
160
6a06907d
XL
161/// When adjusting a receiver we often want to do one of
162///
cdc7bbd5 163/// - Add a `&` (or `&mut`), converting the receiver from `T` to `&T` (or `&mut T`)
6a06907d
XL
164/// - If the receiver has type `*mut T`, convert it to `*const T`
165///
166/// This type tells us which one to do.
167///
168/// Note that in principle we could do both at the same time. For example, when the receiver has
169/// type `T`, we could autoref it to `&T`, then convert to `*const T`. Or, when it has type `*mut
170/// T`, we could convert it to `*const T`, then autoref to `&*const T`. However, currently we do
171/// (at most) one of these. Either the receiver has type `T` and we convert it to `&T` (or with
172/// `mut`), or it has type `*mut T` and we convert it to `*const T`.
5099ac24
FG
173#[derive(Debug, PartialEq, Copy, Clone)]
174pub enum AutorefOrPtrAdjustment {
6a06907d
XL
175 /// Receiver has type `T`, add `&` or `&mut` (it `T` is `mut`), and maybe also "unsize" it.
176 /// Unsizing is used to convert a `[T; N]` to `[T]`, which only makes sense when autorefing.
177 Autoref {
178 mutbl: hir::Mutability,
179
5099ac24
FG
180 /// Indicates that the source expression should be "unsized" to a target type.
181 /// This is special-cased for just arrays unsizing to slices.
182 unsize: bool,
6a06907d
XL
183 },
184 /// Receiver has type `*mut T`, convert to `*const T`
185 ToConstPtr,
186}
187
5099ac24
FG
188impl AutorefOrPtrAdjustment {
189 fn get_unsize(&self) -> bool {
6a06907d 190 match self {
c295e0f8 191 AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => *unsize,
5099ac24 192 AutorefOrPtrAdjustment::ToConstPtr => false,
6a06907d
XL
193 }
194 }
195}
196
487cf647 197#[derive(Debug, Clone)]
1a4d82fc 198pub struct Pick<'tcx> {
dc9dc135 199 pub item: ty::AssocItem,
1a4d82fc 200 pub kind: PickKind<'tcx>,
f035d41b 201 pub import_ids: SmallVec<[LocalDefId; 1]>,
9346a6ac 202
6a06907d 203 /// Indicates that the source expression should be autoderef'd N times
04454e1e
FG
204 /// ```ignore (not-rust)
205 /// A = expr | *expr | **expr | ...
206 /// ```
9346a6ac
AL
207 pub autoderefs: usize,
208
6a06907d
XL
209 /// Indicates that we want to add an autoref (and maybe also unsize it), or if the receiver is
210 /// `*mut T`, convert it to `*const T`.
5099ac24 211 pub autoref_or_ptr_adjustment: Option<AutorefOrPtrAdjustment>,
3c0e092e 212 pub self_ty: Ty<'tcx>,
487cf647
FG
213
214 /// Unstable candidates alongside the stable ones.
215 unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>,
1a4d82fc
JJ
216}
217
3b2f2976 218#[derive(Clone, Debug, PartialEq, Eq)]
1a4d82fc 219pub enum PickKind<'tcx> {
c1a9b12d 220 InherentImplPick,
c1a9b12d
SL
221 ObjectPick,
222 TraitPick,
dfeec247
XL
223 WhereClausePick(
224 // Trait
225 ty::PolyTraitRef<'tcx>,
226 ),
1a4d82fc
JJ
227}
228
62682a34 229pub type PickResult<'tcx> = Result<Pick<'tcx>, MethodError<'tcx>>;
1a4d82fc 230
d9579d0f 231#[derive(PartialEq, Eq, Copy, Clone, Debug)]
c34b1796
AL
232pub enum Mode {
233 // An expression of the form `receiver.method_name(...)`.
234 // Autoderefs are performed on `receiver`, lookup is done based on the
9c376795 235 // `self` argument of the method, and static methods aren't considered.
c34b1796 236 MethodCall,
d9579d0f 237 // An expression of the form `Type::item` or `<T>::item`.
c34b1796
AL
238 // No autoderefs are performed, lookup is done based on the type each
239 // implementation is for, and static methods are included.
c30ab7b3 240 Path,
c34b1796
AL
241}
242
3b2f2976
XL
243#[derive(PartialEq, Eq, Copy, Clone, Debug)]
244pub enum ProbeScope {
245 // Assemble candidates coming only from traits in scope.
246 TraitsInScope,
247
248 // Assemble candidates coming from all traits.
249 AllTraits,
250}
251
dc9dc135 252impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32a655c1
SL
253 /// This is used to offer suggestions to users. It returns methods
254 /// that could have been called which have the desired return
255 /// type. Some effort is made to rule out methods that, if called,
256 /// would result in an error (basically, the same criteria we
257 /// would use to decide if a method is a plausible fit for
258 /// ambiguity purposes).
2b03887a 259 #[instrument(level = "debug", skip(self, candidate_filter))]
dfeec247
XL
260 pub fn probe_for_return_type(
261 &self,
262 span: Span,
263 mode: Mode,
264 return_type: Ty<'tcx>,
265 self_ty: Ty<'tcx>,
266 scope_expr_id: hir::HirId,
2b03887a 267 candidate_filter: impl Fn(&ty::AssocItem) -> bool,
dfeec247 268 ) -> Vec<ty::AssocItem> {
dfeec247
XL
269 let method_names = self
270 .probe_op(
271 span,
272 mode,
273 None,
274 Some(return_type),
275 IsSuggestion(true),
276 self_ty,
277 scope_expr_id,
278 ProbeScope::AllTraits,
2b03887a 279 |probe_cx| Ok(probe_cx.candidate_method_names(candidate_filter)),
dfeec247 280 )
29967ef6 281 .unwrap_or_default();
dfeec247
XL
282 method_names
283 .iter()
284 .flat_map(|&method_name| {
285 self.probe_op(
286 span,
287 mode,
288 Some(method_name),
289 Some(return_type),
290 IsSuggestion(true),
291 self_ty,
292 scope_expr_id,
293 ProbeScope::AllTraits,
294 |probe_cx| probe_cx.pick(),
295 )
296 .ok()
297 .map(|pick| pick.item)
298 })
32a655c1
SL
299 .collect()
300 }
301
f2b60f7d 302 #[instrument(level = "debug", skip(self))]
dfeec247
XL
303 pub fn probe_for_name(
304 &self,
dfeec247 305 mode: Mode,
f9f354fc 306 item_name: Ident,
9c376795 307 return_type: Option<Ty<'tcx>>,
dfeec247
XL
308 is_suggestion: IsSuggestion,
309 self_ty: Ty<'tcx>,
310 scope_expr_id: hir::HirId,
311 scope: ProbeScope,
312 ) -> PickResult<'tcx> {
dfeec247 313 self.probe_op(
487cf647 314 item_name.span,
dfeec247
XL
315 mode,
316 Some(item_name),
9c376795 317 return_type,
dfeec247
XL
318 is_suggestion,
319 self_ty,
320 scope_expr_id,
321 scope,
322 |probe_cx| probe_cx.pick(),
323 )
32a655c1 324 }
a7813a04 325
9c376795
FG
326 #[instrument(level = "debug", skip(self))]
327 pub(crate) fn probe_for_name_many(
328 &self,
329 mode: Mode,
330 item_name: Ident,
331 return_type: Option<Ty<'tcx>>,
332 is_suggestion: IsSuggestion,
333 self_ty: Ty<'tcx>,
334 scope_expr_id: hir::HirId,
335 scope: ProbeScope,
336 ) -> Vec<Candidate<'tcx>> {
337 self.probe_op(
338 item_name.span,
339 mode,
340 Some(item_name),
341 return_type,
342 is_suggestion,
343 self_ty,
344 scope_expr_id,
345 scope,
346 |probe_cx| {
347 Ok(probe_cx
348 .inherent_candidates
349 .into_iter()
350 .chain(probe_cx.extension_candidates)
351 .collect())
352 },
353 )
354 .unwrap()
355 }
356
dc9dc135
XL
357 fn probe_op<OP, R>(
358 &'a self,
359 span: Span,
360 mode: Mode,
f9f354fc 361 method_name: Option<Ident>,
dc9dc135
XL
362 return_type: Option<Ty<'tcx>>,
363 is_suggestion: IsSuggestion,
364 self_ty: Ty<'tcx>,
365 scope_expr_id: hir::HirId,
366 scope: ProbeScope,
367 op: OP,
368 ) -> Result<R, MethodError<'tcx>>
369 where
9c376795 370 OP: FnOnce(ProbeContext<'_, 'tcx>) -> Result<R, MethodError<'tcx>>,
32a655c1 371 {
0731742a 372 let mut orig_values = OriginalQueryValues::default();
064997fb 373 let param_env_and_self_ty = self.canonicalize_query(
fc512014 374 ParamEnvAnd { param_env: self.param_env, value: self_ty },
dfeec247
XL
375 &mut orig_values,
376 );
0731742a 377
487cf647
FG
378 let steps = match mode {
379 Mode::MethodCall => self.tcx.method_autoderef_steps(param_env_and_self_ty),
380 Mode::Path => self.probe(|_| {
0731742a
XL
381 // Mode::Path - the deref steps is "trivial". This turns
382 // our CanonicalQuery into a "trivial" QueryResponse. This
383 // is a bit inefficient, but I don't think that writing
384 // special handling for this "trivial case" is a good idea.
385
386 let infcx = &self.infcx;
dfeec247 387 let (ParamEnvAnd { param_env: _, value: self_ty }, canonical_inference_vars) =
0731742a 388 infcx.instantiate_canonical_with_fresh_inference_vars(
dfeec247
XL
389 span,
390 &param_env_and_self_ty,
391 );
392 debug!(
393 "probe_op: Mode::Path, param_env_and_self_ty={:?} self_ty={:?}",
394 param_env_and_self_ty, self_ty
395 );
0731742a 396 MethodAutoderefStepsResult {
5099ac24 397 steps: infcx.tcx.arena.alloc_from_iter([CandidateStep {
0731742a 398 self_ty: self.make_query_response_ignoring_pending_obligations(
dfeec247
XL
399 canonical_inference_vars,
400 self_ty,
401 ),
0731742a
XL
402 autoderefs: 0,
403 from_unsafe_deref: false,
404 unsize: false,
405 }]),
406 opt_bad_ty: None,
dfeec247 407 reached_recursion_limit: false,
0731742a 408 }
487cf647 409 }),
1a4d82fc
JJ
410 };
411
0731742a
XL
412 // If our autoderef loop had reached the recursion limit,
413 // report an overflow error, but continue going on with
414 // the truncated autoderef list.
415 if steps.reached_recursion_limit {
416 self.probe(|_| {
dfeec247
XL
417 let ty = &steps
418 .steps
419 .last()
420 .unwrap_or_else(|| span_bug!(span, "reached the recursion limit in 0 steps?"))
421 .self_ty;
422 let ty = self
423 .probe_instantiate_query_response(span, &orig_values, ty)
0731742a 424 .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
dfeec247 425 autoderef::report_autoderef_recursion_limit_error(self.tcx, span, ty.value);
0731742a
XL
426 });
427 }
428
0731742a
XL
429 // If we encountered an `_` type or an error type during autoderef, this is
430 // ambiguous.
431 if let Some(bad_ty) = &steps.opt_bad_ty {
432 if is_suggestion.0 {
433 // Ambiguity was encountered during a suggestion. Just keep going.
434 debug!("ProbeContext: encountered ambiguity in suggestion");
435 } else if bad_ty.reached_raw_pointer && !self.tcx.features().arbitrary_self_types {
436 // this case used to be allowed by the compiler,
437 // so we do a future-compat lint here for the 2015 edition
438 // (see https://github.com/rust-lang/rust/issues/46906)
439 if self.tcx.sess.rust_2018() {
1b1a35ee 440 self.tcx.sess.emit_err(MethodCallOnUnknownType { span });
0731742a 441 } else {
74b04a01 442 self.tcx.struct_span_lint_hir(
0731742a
XL
443 lint::builtin::TYVAR_BEHIND_RAW_POINTER,
444 scope_expr_id,
445 span,
2b03887a
FG
446 "type annotations needed",
447 |lint| lint,
dfeec247 448 );
0731742a
XL
449 }
450 } else {
451 // Encountered a real ambiguity, so abort the lookup. If `ty` is not
452 // an `Err`, report the right "type annotations needed" error pointing
453 // to it.
454 let ty = &bad_ty.ty;
dfeec247
XL
455 let ty = self
456 .probe_instantiate_query_response(span, &orig_values, ty)
0731742a
XL
457 .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
458 let ty = self.structurally_resolved_type(span, ty.value);
1b1a35ee 459 assert!(matches!(ty.kind(), ty::Error(_)));
5e7ed085
FG
460 return Err(MethodError::NoMatch(NoMatchData {
461 static_candidates: Vec::new(),
462 unsatisfied_predicates: Vec::new(),
463 out_of_scope_traits: Vec::new(),
464 lev_candidate: None,
dfeec247 465 mode,
5e7ed085 466 }));
0731742a
XL
467 }
468 }
469
dfeec247 470 debug!("ProbeContext: steps for self_ty={:?} are {:?}", self_ty, steps);
0731742a 471
a7813a04
XL
472 // this creates one big transaction so that all type variables etc
473 // that we create during the probe process are removed later
474 self.probe(|_| {
0531ce1d 475 let mut probe_cx = ProbeContext::new(
dfeec247
XL
476 self,
477 span,
478 mode,
479 method_name,
480 return_type,
9c376795 481 &orig_values,
dfeec247 482 steps.steps,
cdc7bbd5 483 scope_expr_id,
0531ce1d 484 );
3b2f2976 485
a7813a04 486 probe_cx.assemble_inherent_candidates();
3b2f2976 487 match scope {
dfeec247 488 ProbeScope::TraitsInScope => {
9c376795 489 probe_cx.assemble_extension_candidates_for_traits_in_scope()
dfeec247 490 }
5869c6ff 491 ProbeScope::AllTraits => probe_cx.assemble_extension_candidates_for_all_traits(),
3b2f2976 492 };
32a655c1 493 op(probe_cx)
a7813a04
XL
494 })
495 }
0731742a
XL
496}
497
f035d41b 498pub fn provide(providers: &mut ty::query::Providers) {
0731742a
XL
499 providers.method_autoderef_steps = method_autoderef_steps;
500}
501
dc9dc135
XL
502fn method_autoderef_steps<'tcx>(
503 tcx: TyCtxt<'tcx>,
504 goal: CanonicalTyGoal<'tcx>,
505) -> MethodAutoderefStepsResult<'tcx> {
0731742a 506 debug!("method_autoderef_steps({:?})", goal);
85aaf69f 507
2b03887a
FG
508 let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal);
509 let ParamEnvAnd { param_env, value: self_ty } = goal;
510
487cf647
FG
511 let mut autoderef = Autoderef::new(infcx, param_env, hir::CRATE_HIR_ID, DUMMY_SP, self_ty)
512 .include_raw_pointers()
513 .silence_errors();
2b03887a
FG
514 let mut reached_raw_pointer = false;
515 let mut steps: Vec<_> = autoderef
516 .by_ref()
517 .map(|(ty, d)| {
518 let step = CandidateStep {
519 self_ty: infcx
520 .make_query_response_ignoring_pending_obligations(inference_vars.clone(), ty),
521 autoderefs: d,
522 from_unsafe_deref: reached_raw_pointer,
523 unsize: false,
524 };
525 if let ty::RawPtr(_) = ty.kind() {
526 // all the subsequent steps will be from_unsafe_deref
527 reached_raw_pointer = true;
a7813a04 528 }
2b03887a
FG
529 step
530 })
531 .collect();
532
533 let final_ty = autoderef.final_ty(true);
534 let opt_bad_ty = match final_ty.kind() {
535 ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
536 reached_raw_pointer,
537 ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
538 }),
539 ty::Array(elem_ty, _) => {
540 let dereferences = steps.len() - 1;
541
542 steps.push(CandidateStep {
543 self_ty: infcx.make_query_response_ignoring_pending_obligations(
544 inference_vars,
545 infcx.tcx.mk_slice(*elem_ty),
546 ),
547 autoderefs: dereferences,
548 // this could be from an unsafe deref if we had
549 // a *mut/const [T; N]
550 from_unsafe_deref: reached_raw_pointer,
551 unsize: true,
552 });
3157f602 553
2b03887a 554 None
0731742a 555 }
2b03887a
FG
556 _ => None,
557 };
558
559 debug!("method_autoderef_steps: steps={:?} opt_bad_ty={:?}", steps, opt_bad_ty);
560
561 MethodAutoderefStepsResult {
562 steps: tcx.arena.alloc_from_iter(steps),
563 opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)),
564 reached_recursion_limit: autoderef.reached_recursion_limit(),
565 }
1a4d82fc
JJ
566}
567
dc9dc135
XL
568impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
569 fn new(
570 fcx: &'a FnCtxt<'a, 'tcx>,
571 span: Span,
572 mode: Mode,
f9f354fc 573 method_name: Option<Ident>,
dc9dc135 574 return_type: Option<Ty<'tcx>>,
9c376795 575 orig_steps_var_values: &'a OriginalQueryValues<'tcx>,
5099ac24 576 steps: &'tcx [CandidateStep<'tcx>],
cdc7bbd5 577 scope_expr_id: hir::HirId,
dc9dc135 578 ) -> ProbeContext<'a, 'tcx> {
1a4d82fc 579 ProbeContext {
3b2f2976
XL
580 fcx,
581 span,
582 mode,
ea8adc8c
XL
583 method_name,
584 return_type,
1a4d82fc
JJ
585 inherent_candidates: Vec::new(),
586 extension_candidates: Vec::new(),
0bf4aa26 587 impl_dups: FxHashSet::default(),
0731742a
XL
588 orig_steps_var_values,
589 steps,
ea8adc8c 590 allow_similar_names: false,
54a0048b 591 private_candidate: None,
9c376795
FG
592 static_candidates: RefCell::new(Vec::new()),
593 unsatisfied_predicates: RefCell::new(Vec::new()),
cdc7bbd5 594 scope_expr_id,
1a4d82fc
JJ
595 }
596 }
597
85aaf69f
SL
598 fn reset(&mut self) {
599 self.inherent_candidates.clear();
600 self.extension_candidates.clear();
601 self.impl_dups.clear();
54a0048b 602 self.private_candidate = None;
9c376795
FG
603 self.static_candidates.borrow_mut().clear();
604 self.unsatisfied_predicates.borrow_mut().clear();
85aaf69f
SL
605 }
606
1a4d82fc
JJ
607 ///////////////////////////////////////////////////////////////////////////
608 // CANDIDATE ASSEMBLY
609
dfeec247 610 fn push_candidate(&mut self, candidate: Candidate<'tcx>, is_inherent: bool) {
ea8adc8c
XL
611 let is_accessible = if let Some(name) = self.method_name {
612 let item = candidate.item;
064997fb
FG
613 let def_scope = self
614 .tcx
615 .adjust_ident_and_get_scope(name, item.container_id(self.tcx), self.body_id)
616 .1;
617 item.visibility(self.tcx).is_accessible_from(def_scope, self.tcx)
7cac9316
XL
618 } else {
619 true
620 };
621 if is_accessible {
ea8adc8c
XL
622 if is_inherent {
623 self.inherent_candidates.push(candidate);
624 } else {
625 self.extension_candidates.push(candidate);
626 }
7cac9316 627 } else if self.private_candidate.is_none() {
ba9703b0
XL
628 self.private_candidate =
629 Some((candidate.item.kind.as_def_kind(), candidate.item.def_id));
7cac9316
XL
630 }
631 }
632
1a4d82fc 633 fn assemble_inherent_candidates(&mut self) {
5099ac24 634 for step in self.steps.iter() {
0731742a 635 self.assemble_probe(&step.self_ty);
1a4d82fc
JJ
636 }
637 }
638
dc9dc135 639 fn assemble_probe(&mut self, self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>) {
c30ab7b3 640 debug!("assemble_probe: self_ty={:?}", self_ty);
5e7ed085
FG
641 let raw_self_ty = self_ty.value.value;
642 match *raw_self_ty.kind() {
c295e0f8 643 ty::Dynamic(data, ..) if let Some(p) = data.principal() => {
94222f64
XL
644 // Subtle: we can't use `instantiate_query_response` here: using it will
645 // commit to all of the type equalities assumed by inference going through
646 // autoderef (see the `method-probe-no-guessing` test).
647 //
648 // However, in this code, it is OK if we end up with an object type that is
649 // "more general" than the object type that we are evaluating. For *every*
650 // object type `MY_OBJECT`, a function call that goes through a trait-ref
651 // of the form `<MY_OBJECT as SuperTraitOf(MY_OBJECT)>::func` is a valid
652 // `ObjectCandidate`, and it should be discoverable "exactly" through one
653 // of the iterations in the autoderef loop, so there is no problem with it
654 // being discoverable in another one of these iterations.
655 //
656 // Using `instantiate_canonical_with_fresh_inference_vars` on our
657 // `Canonical<QueryResponse<Ty<'tcx>>>` and then *throwing away* the
658 // `CanonicalVarValues` will exactly give us such a generalization - it
659 // will still match the original object type, but it won't pollute our
660 // type variables in any form, so just do that!
661 let (QueryResponse { value: generalized_self_ty, .. }, _ignored_var_values) =
662 self.fcx
c295e0f8 663 .instantiate_canonical_with_fresh_inference_vars(self.span, self_ty);
94222f64
XL
664
665 self.assemble_inherent_candidates_from_object(generalized_self_ty);
666 self.assemble_inherent_impl_candidates_for_type(p.def_id());
04454e1e
FG
667 if self.tcx.has_attr(p.def_id(), sym::rustc_has_incoherent_inherent_impls) {
668 self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
669 }
1a4d82fc 670 }
b7449926 671 ty::Adt(def, _) => {
04454e1e
FG
672 let def_id = def.did();
673 self.assemble_inherent_impl_candidates_for_type(def_id);
674 if self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) {
675 self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
676 }
1a4d82fc 677 }
b7449926 678 ty::Foreign(did) => {
abe05a73 679 self.assemble_inherent_impl_candidates_for_type(did);
04454e1e
FG
680 if self.tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
681 self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
682 }
abe05a73 683 }
b7449926 684 ty::Param(p) => {
0731742a 685 self.assemble_inherent_candidates_from_param(p);
1a4d82fc 686 }
5e7ed085
FG
687 ty::Bool
688 | ty::Char
689 | ty::Int(_)
690 | ty::Uint(_)
691 | ty::Float(_)
692 | ty::Str
693 | ty::Array(..)
694 | ty::Slice(_)
695 | ty::RawPtr(_)
696 | ty::Ref(..)
697 | ty::Never
698 | ty::Tuple(..) => self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty),
c30ab7b3 699 _ => {}
1a4d82fc
JJ
700 }
701 }
702
5e7ed085 703 fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
923072b8 704 let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsInfer) else {
5e7ed085
FG
705 bug!("unexpected incoherent type: {:?}", self_ty)
706 };
707 for &impl_def_id in self.tcx.incoherent_impls(simp) {
c34b1796
AL
708 self.assemble_inherent_impl_probe(impl_def_id);
709 }
710 }
711
e9174d1e 712 fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
7cac9316 713 let impl_def_ids = self.tcx.at(self.span).inherent_impls(def_id);
cc61c64b
XL
714 for &impl_def_id in impl_def_ids.iter() {
715 self.assemble_inherent_impl_probe(impl_def_id);
1a4d82fc
JJ
716 }
717 }
718
e9174d1e 719 fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
1a4d82fc
JJ
720 if !self.impl_dups.insert(impl_def_id) {
721 return; // already visited
722 }
723
724 debug!("assemble_inherent_impl_probe {:?}", impl_def_id);
725
32a655c1
SL
726 for item in self.impl_or_trait_item(impl_def_id) {
727 if !self.has_applicable_self(&item) {
728 // No receiver declared. Not a candidate.
04454e1e 729 self.record_static_candidate(CandidateSource::Impl(impl_def_id));
dfeec247 730 continue;
32a655c1 731 }
1a4d82fc 732
32a655c1 733 let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
064997fb 734 let impl_ty = impl_ty.subst(self.tcx, impl_substs);
54a0048b 735
c295e0f8
XL
736 debug!("impl_ty: {:?}", impl_ty);
737
32a655c1 738 // Determine the receiver type that the method itself expects.
c295e0f8
XL
739 let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(&item, impl_ty, impl_substs);
740 debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
32a655c1
SL
741
742 // We can't use normalize_associated_types_in as it will pollute the
743 // fcx's fulfillment context after this probe is over.
c295e0f8
XL
744 // Note: we only normalize `xform_self_ty` here since the normalization
745 // of the return type can lead to inference results that prohibit
5e7ed085 746 // valid candidates from being found, see issue #85671
c295e0f8
XL
747 // FIXME Postponing the normalization of the return type likely only hides a deeper bug,
748 // which might be caused by the `param_env` itself. The clauses of the `param_env`
749 // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
5e7ed085 750 // see issue #89650
32a655c1 751 let cause = traits::ObligationCause::misc(self.span, self.body_id);
487cf647
FG
752 let InferOk { value: xform_self_ty, obligations } =
753 self.fcx.at(&cause, self.param_env).normalize(xform_self_ty);
754
dfeec247 755 debug!(
c295e0f8 756 "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}",
dfeec247
XL
757 xform_self_ty, xform_ret_ty
758 );
759
760 self.push_candidate(
761 Candidate {
762 xform_self_ty,
763 xform_ret_ty,
764 item,
765 kind: InherentImplCandidate(impl_substs, obligations),
766 import_ids: smallvec![],
767 },
768 true,
769 );
32a655c1 770 }
1a4d82fc
JJ
771 }
772
dfeec247
XL
773 fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'tcx>) {
774 debug!("assemble_inherent_candidates_from_object(self_ty={:?})", self_ty);
1a4d82fc 775
1b1a35ee 776 let principal = match self_ty.kind() {
0731742a 777 ty::Dynamic(ref data, ..) => Some(data),
dfeec247
XL
778 _ => None,
779 }
780 .and_then(|data| data.principal())
781 .unwrap_or_else(|| {
782 span_bug!(
783 self.span,
784 "non-object {:?} in assemble_inherent_candidates_from_object",
785 self_ty
786 )
0731742a
XL
787 });
788
fc512014
XL
789 // It is illegal to invoke a method on a trait instance that refers to
790 // the `Self` type. An [`ObjectSafetyViolation::SupertraitSelf`] error
791 // will be reported by `object_safety.rs` if the method refers to the
792 // `Self` type anywhere other than the receiver. Here, we use a
793 // substitution that replaces `Self` with the object type itself. Hence,
5869c6ff 794 // a `&self` method will wind up with an argument type like `&dyn Trait`.
9e0c209e 795 let trait_ref = principal.with_self_ty(self.tcx, self_ty);
a1dfa0c6 796 self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
fc512014 797 let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
1a4d82fc 798
ea8adc8c 799 let (xform_self_ty, xform_ret_ty) =
c30ab7b3 800 this.xform_self_ty(&item, new_trait_ref.self_ty(), new_trait_ref.substs);
dfeec247
XL
801 this.push_candidate(
802 Candidate {
803 xform_self_ty,
804 xform_ret_ty,
805 item,
806 kind: ObjectCandidate,
807 import_ids: smallvec![],
808 },
809 true,
810 );
1a4d82fc
JJ
811 });
812 }
813
48663c56 814 fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
dc9dc135 815 // FIXME: do we want to commit to this behavior for param bounds?
f035d41b 816 debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
1a4d82fc 817
29967ef6 818 let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| {
5869c6ff 819 let bound_predicate = predicate.kind();
29967ef6 820 match bound_predicate.skip_binder() {
487cf647 821 ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
29967ef6
XL
822 match *trait_predicate.trait_ref.self_ty().kind() {
823 ty::Param(p) if p == param_ty => {
824 Some(bound_predicate.rebind(trait_predicate.trait_ref))
3dfed10e 825 }
29967ef6 826 _ => None,
3dfed10e 827 }
29967ef6 828 }
5869c6ff 829 ty::PredicateKind::Subtype(..)
94222f64 830 | ty::PredicateKind::Coerce(..)
487cf647
FG
831 | ty::PredicateKind::Clause(ty::Clause::Projection(..))
832 | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
5869c6ff
XL
833 | ty::PredicateKind::WellFormed(..)
834 | ty::PredicateKind::ObjectSafe(..)
835 | ty::PredicateKind::ClosureKind(..)
487cf647 836 | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
5869c6ff
XL
837 | ty::PredicateKind::ConstEvaluatable(..)
838 | ty::PredicateKind::ConstEquate(..)
487cf647 839 | ty::PredicateKind::Ambiguous
5869c6ff 840 | ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
29967ef6
XL
841 }
842 });
1a4d82fc 843
a1dfa0c6 844 self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
fc512014 845 let trait_ref = this.erase_late_bound_regions(poly_trait_ref);
1a4d82fc 846
ea8adc8c
XL
847 let (xform_self_ty, xform_ret_ty) =
848 this.xform_self_ty(&item, trait_ref.self_ty(), trait_ref.substs);
1a4d82fc 849
1a4d82fc
JJ
850 // Because this trait derives from a where-clause, it
851 // should not contain any inference variables or other
852 // artifacts. This means it is safe to put into the
853 // `WhereClauseCandidate` and (eventually) into the
854 // `WhereClausePick`.
9e0c209e 855 assert!(!trait_ref.substs.needs_infer());
1a4d82fc 856
dfeec247
XL
857 this.push_candidate(
858 Candidate {
859 xform_self_ty,
860 xform_ret_ty,
861 item,
862 kind: WhereClauseCandidate(poly_trait_ref),
863 import_ids: smallvec![],
864 },
865 true,
866 );
1a4d82fc
JJ
867 });
868 }
869
870 // Do a search through a list of bounds, using a callback to actually
871 // create the candidates.
dc9dc135
XL
872 fn elaborate_bounds<F>(
873 &mut self,
874 bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
875 mut mk_cand: F,
876 ) where
877 F: for<'b> FnMut(&mut ProbeContext<'b, 'tcx>, ty::PolyTraitRef<'tcx>, ty::AssocItem),
1a4d82fc 878 {
a7813a04 879 let tcx = self.tcx;
1a4d82fc 880 for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
a1dfa0c6 881 debug!("elaborate_bounds(bound_trait_ref={:?})", bound_trait_ref);
32a655c1
SL
882 for item in self.impl_or_trait_item(bound_trait_ref.def_id()) {
883 if !self.has_applicable_self(&item) {
04454e1e 884 self.record_static_candidate(CandidateSource::Trait(bound_trait_ref.def_id()));
32a655c1
SL
885 } else {
886 mk_cand(self, bound_trait_ref, item);
c30ab7b3 887 }
1a4d82fc
JJ
888 }
889 }
890 }
891
9c376795 892 fn assemble_extension_candidates_for_traits_in_scope(&mut self) {
0bf4aa26 893 let mut duplicates = FxHashSet::default();
9c376795 894 let opt_applicable_traits = self.tcx.in_scope_traits(self.scope_expr_id);
85aaf69f 895 if let Some(applicable_traits) = opt_applicable_traits {
ea8adc8c 896 for trait_candidate in applicable_traits.iter() {
a7813a04 897 let trait_did = trait_candidate.def_id;
1a4d82fc 898 if duplicates.insert(trait_did) {
5869c6ff 899 self.assemble_extension_candidates_for_trait(
74b04a01
XL
900 &trait_candidate.import_ids,
901 trait_did,
902 );
1a4d82fc
JJ
903 }
904 }
905 }
85aaf69f
SL
906 }
907
5869c6ff 908 fn assemble_extension_candidates_for_all_traits(&mut self) {
0bf4aa26 909 let mut duplicates = FxHashSet::default();
8bb4bdeb 910 for trait_info in suggest::all_traits(self.tcx) {
85aaf69f 911 if duplicates.insert(trait_info.def_id) {
5869c6ff 912 self.assemble_extension_candidates_for_trait(&smallvec![], trait_info.def_id);
85aaf69f
SL
913 }
914 }
1a4d82fc
JJ
915 }
916
487cf647 917 fn matches_return_type(
dfeec247
XL
918 &self,
919 method: &ty::AssocItem,
920 self_ty: Option<Ty<'tcx>>,
921 expected: Ty<'tcx>,
922 ) -> bool {
48663c56 923 match method.kind {
ba9703b0 924 ty::AssocKind::Fn => {
04454e1e 925 let fty = self.tcx.bound_fn_sig(method.def_id);
32a655c1
SL
926 self.probe(|_| {
927 let substs = self.fresh_substs_for_item(self.span, method.def_id);
ea8adc8c 928 let fty = fty.subst(self.tcx, substs);
923072b8 929 let fty =
fc512014 930 self.replace_bound_vars_with_fresh_vars(self.span, infer::FnCall, fty);
ea8adc8c
XL
931
932 if let Some(self_ty) = self_ty {
dfeec247
XL
933 if self
934 .at(&ObligationCause::dummy(), self.param_env)
935 .sup(fty.inputs()[0], self_ty)
936 .is_err()
ea8adc8c 937 {
dfeec247 938 return false;
ea8adc8c
XL
939 }
940 }
941 self.can_sub(self.param_env, fty.output(), expected).is_ok()
32a655c1
SL
942 })
943 }
944 _ => false,
945 }
946 }
947
dfeec247
XL
948 fn assemble_extension_candidates_for_trait(
949 &mut self,
f035d41b 950 import_ids: &SmallVec<[LocalDefId; 1]>,
dfeec247 951 trait_def_id: DefId,
5869c6ff 952 ) {
dfeec247 953 debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id);
ea8adc8c 954 let trait_substs = self.fresh_item_substs(trait_def_id);
9c376795 955 let trait_ref = self.tcx.mk_trait_ref(trait_def_id, trait_substs);
1a4d82fc 956
532ac7d7 957 if self.tcx.is_trait_alias(trait_def_id) {
c295e0f8
XL
958 // For trait aliases, assume all supertraits are relevant.
959 let bounds = iter::once(ty::Binder::dummy(trait_ref));
532ac7d7 960 self.elaborate_bounds(bounds, |this, new_trait_ref, item| {
fc512014 961 let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
532ac7d7
XL
962
963 let (xform_self_ty, xform_ret_ty) =
964 this.xform_self_ty(&item, new_trait_ref.self_ty(), new_trait_ref.substs);
dfeec247
XL
965 this.push_candidate(
966 Candidate {
967 xform_self_ty,
968 xform_ret_ty,
969 item,
970 import_ids: import_ids.clone(),
971 kind: TraitCandidate(new_trait_ref),
972 },
f035d41b 973 false,
dfeec247 974 );
532ac7d7
XL
975 });
976 } else {
977 debug_assert!(self.tcx.is_trait(trait_def_id));
9c376795
FG
978 if self.tcx.trait_is_auto(trait_def_id) {
979 return;
980 }
532ac7d7
XL
981 for item in self.impl_or_trait_item(trait_def_id) {
982 // Check whether `trait_def_id` defines a method with suitable name.
983 if !self.has_applicable_self(&item) {
984 debug!("method has inapplicable self");
04454e1e 985 self.record_static_candidate(CandidateSource::Trait(trait_def_id));
532ac7d7
XL
986 continue;
987 }
1a4d82fc 988
532ac7d7
XL
989 let (xform_self_ty, xform_ret_ty) =
990 self.xform_self_ty(&item, trait_ref.self_ty(), trait_substs);
dfeec247
XL
991 self.push_candidate(
992 Candidate {
993 xform_self_ty,
994 xform_ret_ty,
995 item,
996 import_ids: import_ids.clone(),
997 kind: TraitCandidate(trait_ref),
998 },
999 false,
1000 );
532ac7d7 1001 }
32a655c1 1002 }
1a4d82fc
JJ
1003 }
1004
2b03887a
FG
1005 fn candidate_method_names(
1006 &self,
1007 candidate_filter: impl Fn(&ty::AssocItem) -> bool,
1008 ) -> Vec<Ident> {
0bf4aa26 1009 let mut set = FxHashSet::default();
dfeec247
XL
1010 let mut names: Vec<_> = self
1011 .inherent_candidates
ea8adc8c
XL
1012 .iter()
1013 .chain(&self.extension_candidates)
2b03887a 1014 .filter(|candidate| candidate_filter(&candidate.item))
ea8adc8c
XL
1015 .filter(|candidate| {
1016 if let Some(return_ty) = self.return_type {
1017 self.matches_return_type(&candidate.item, None, return_ty)
1018 } else {
1019 true
1020 }
1021 })
5099ac24 1022 .map(|candidate| candidate.item.ident(self.tcx))
ea8adc8c
XL
1023 .filter(|&name| set.insert(name))
1024 .collect();
32a655c1 1025
532ac7d7 1026 // Sort them by the name so we have a stable result.
a2a8927a 1027 names.sort_by(|a, b| a.as_str().partial_cmp(b.as_str()).unwrap());
32a655c1
SL
1028 names
1029 }
1030
1a4d82fc
JJ
1031 ///////////////////////////////////////////////////////////////////////////
1032 // THE ACTUAL SEARCH
1033
1034 fn pick(mut self) -> PickResult<'tcx> {
ea8adc8c 1035 assert!(self.method_name.is_some());
32a655c1 1036
3157f602
XL
1037 if let Some(r) = self.pick_core() {
1038 return r;
85aaf69f 1039 }
1a4d82fc 1040
74b04a01 1041 debug!("pick: actual search failed, assemble diagnostics");
532ac7d7 1042
9c376795 1043 let static_candidates = std::mem::take(self.static_candidates.get_mut());
a1dfa0c6 1044 let private_candidate = self.private_candidate.take();
9c376795 1045 let unsatisfied_predicates = std::mem::take(self.unsatisfied_predicates.get_mut());
85aaf69f
SL
1046
1047 // things failed, so lets look at all traits, for diagnostic purposes now:
1048 self.reset();
1049
1050 let span = self.span;
a7813a04 1051 let tcx = self.tcx;
85aaf69f 1052
5869c6ff 1053 self.assemble_extension_candidates_for_all_traits();
85aaf69f
SL
1054
1055 let out_of_scope_traits = match self.pick_core() {
064997fb 1056 Some(Ok(p)) => vec![p.item.container_id(self.tcx)],
dfeec247
XL
1057 Some(Err(MethodError::Ambiguity(v))) => v
1058 .into_iter()
1059 .map(|source| match source {
04454e1e
FG
1060 CandidateSource::Trait(id) => id,
1061 CandidateSource::Impl(impl_id) => match tcx.trait_id_of_impl(impl_id) {
dfeec247
XL
1062 Some(id) => id,
1063 None => span_bug!(span, "found inherent method when looking at traits"),
1064 },
1065 })
1066 .collect(),
1067 Some(Err(MethodError::NoMatch(NoMatchData {
1068 out_of_scope_traits: others, ..
1069 }))) => {
85aaf69f
SL
1070 assert!(others.is_empty());
1071 vec![]
1a4d82fc 1072 }
54a0048b 1073 _ => vec![],
85aaf69f
SL
1074 };
1075
48663c56
XL
1076 if let Some((kind, def_id)) = private_candidate {
1077 return Err(MethodError::PrivateMatch(kind, def_id, out_of_scope_traits));
54a0048b 1078 }
ea8adc8c 1079 let lev_candidate = self.probe_for_lev_candidate()?;
54a0048b 1080
5e7ed085 1081 Err(MethodError::NoMatch(NoMatchData {
dfeec247
XL
1082 static_candidates,
1083 unsatisfied_predicates,
1084 out_of_scope_traits,
1085 lev_candidate,
5e7ed085
FG
1086 mode: self.mode,
1087 }))
85aaf69f
SL
1088 }
1089
9c376795 1090 fn pick_core(&self) -> Option<PickResult<'tcx>> {
487cf647 1091 let pick = self.pick_all_method(Some(&mut vec![]));
3c0e092e
XL
1092
1093 // In this case unstable picking is done by `pick_method`.
064997fb 1094 if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable {
3c0e092e
XL
1095 return pick;
1096 }
1a4d82fc 1097
487cf647
FG
1098 if pick.is_none() {
1099 return self.pick_all_method(None);
3c0e092e 1100 }
487cf647 1101 pick
3c0e092e
XL
1102 }
1103
1104 fn pick_all_method(
9c376795 1105 &self,
3c0e092e
XL
1106 mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
1107 ) -> Option<PickResult<'tcx>> {
9c376795 1108 self.steps
ea8adc8c
XL
1109 .iter()
1110 .filter(|step| {
3c0e092e 1111 debug!("pick_all_method: step={:?}", step);
ff7c6d11
XL
1112 // skip types that are from a type error or that would require dereferencing
1113 // a raw pointer
1114 !step.self_ty.references_error() && !step.from_unsafe_deref
dfeec247 1115 })
9c376795 1116 .find_map(|step| {
dfeec247
XL
1117 let InferOk { value: self_ty, obligations: _ } = self
1118 .fcx
1119 .probe_instantiate_query_response(
1120 self.span,
1121 &self.orig_steps_var_values,
1122 &step.self_ty,
1123 )
1124 .unwrap_or_else(|_| {
0731742a
XL
1125 span_bug!(self.span, "{:?} was applicable but now isn't?", step.self_ty)
1126 });
3c0e092e
XL
1127 self.pick_by_value_method(step, self_ty, unstable_candidates.as_deref_mut())
1128 .or_else(|| {
1129 self.pick_autorefd_method(
1130 step,
1131 self_ty,
1132 hir::Mutability::Not,
1133 unstable_candidates.as_deref_mut(),
1134 )
1135 .or_else(|| {
1136 self.pick_autorefd_method(
1137 step,
1138 self_ty,
1139 hir::Mutability::Mut,
1140 unstable_candidates.as_deref_mut(),
1141 )
1142 })
1143 .or_else(|| {
1144 self.pick_const_ptr_method(
1145 step,
1146 self_ty,
1147 unstable_candidates.as_deref_mut(),
1148 )
1149 })
1150 })
dfeec247 1151 })
1a4d82fc
JJ
1152 }
1153
6a06907d
XL
1154 /// For each type `T` in the step list, this attempts to find a method where
1155 /// the (transformed) self type is exactly `T`. We do however do one
1156 /// transformation on the adjustment: if we are passing a region pointer in,
1157 /// we will potentially *reborrow* it to a shorter lifetime. This allows us
1158 /// to transparently pass `&mut` pointers, in particular, without consuming
1159 /// them for their entire lifetime.
dc9dc135 1160 fn pick_by_value_method(
9c376795 1161 &self,
dc9dc135
XL
1162 step: &CandidateStep<'tcx>,
1163 self_ty: Ty<'tcx>,
3c0e092e 1164 unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
dc9dc135 1165 ) -> Option<PickResult<'tcx>> {
9346a6ac
AL
1166 if step.unsize {
1167 return None;
1168 }
1a4d82fc 1169
3c0e092e 1170 self.pick_method(self_ty, unstable_candidates).map(|r| {
c30ab7b3
SL
1171 r.map(|mut pick| {
1172 pick.autoderefs = step.autoderefs;
1a4d82fc 1173
c30ab7b3 1174 // Insert a `&*` or `&mut *` if this is a reference type:
1b1a35ee 1175 if let ty::Ref(_, _, mutbl) = *step.self_ty.value.value.kind() {
c30ab7b3 1176 pick.autoderefs += 1;
6a06907d
XL
1177 pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
1178 mutbl,
5099ac24 1179 unsize: pick.autoref_or_ptr_adjustment.map_or(false, |a| a.get_unsize()),
6a06907d 1180 })
c30ab7b3 1181 }
9346a6ac 1182
c30ab7b3
SL
1183 pick
1184 })
1185 })
1a4d82fc
JJ
1186 }
1187
dc9dc135 1188 fn pick_autorefd_method(
9c376795 1189 &self,
dc9dc135
XL
1190 step: &CandidateStep<'tcx>,
1191 self_ty: Ty<'tcx>,
1192 mutbl: hir::Mutability,
3c0e092e 1193 unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
dc9dc135 1194 ) -> Option<PickResult<'tcx>> {
a7813a04 1195 let tcx = self.tcx;
1a4d82fc 1196
ba9703b0 1197 // In general, during probing we erase regions.
48663c56 1198 let region = tcx.lifetimes.re_erased;
1a4d82fc 1199
dfeec247 1200 let autoref_ty = tcx.mk_ref(region, ty::TypeAndMut { ty: self_ty, mutbl });
3c0e092e 1201 self.pick_method(autoref_ty, unstable_candidates).map(|r| {
ea8adc8c
XL
1202 r.map(|mut pick| {
1203 pick.autoderefs = step.autoderefs;
5099ac24
FG
1204 pick.autoref_or_ptr_adjustment =
1205 Some(AutorefOrPtrAdjustment::Autoref { mutbl, unsize: step.unsize });
6a06907d
XL
1206 pick
1207 })
1208 })
1209 }
1210
1211 /// If `self_ty` is `*mut T` then this picks `*const T` methods. The reason why we have a
1212 /// special case for this is because going from `*mut T` to `*const T` with autoderefs and
1213 /// autorefs would require dereferencing the pointer, which is not safe.
1214 fn pick_const_ptr_method(
9c376795 1215 &self,
6a06907d
XL
1216 step: &CandidateStep<'tcx>,
1217 self_ty: Ty<'tcx>,
3c0e092e 1218 unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
6a06907d
XL
1219 ) -> Option<PickResult<'tcx>> {
1220 // Don't convert an unsized reference to ptr
1221 if step.unsize {
1222 return None;
1223 }
1224
5e7ed085
FG
1225 let &ty::RawPtr(ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }) = self_ty.kind() else {
1226 return None;
6a06907d
XL
1227 };
1228
1229 let const_self_ty = ty::TypeAndMut { ty, mutbl: hir::Mutability::Not };
1230 let const_ptr_ty = self.tcx.mk_ptr(const_self_ty);
3c0e092e 1231 self.pick_method(const_ptr_ty, unstable_candidates).map(|r| {
6a06907d
XL
1232 r.map(|mut pick| {
1233 pick.autoderefs = step.autoderefs;
1234 pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::ToConstPtr);
ea8adc8c 1235 pick
c30ab7b3 1236 })
ea8adc8c 1237 })
1a4d82fc
JJ
1238 }
1239
9c376795 1240 fn pick_method_with_unstable(&self, self_ty: Ty<'tcx>) -> Option<PickResult<'tcx>> {
3c0e092e 1241 debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty));
1a4d82fc 1242
62682a34 1243 let mut possibly_unsatisfied_predicates = Vec::new();
0531ce1d 1244
dfeec247
XL
1245 for (kind, candidates) in
1246 &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
1247 {
0531ce1d
XL
1248 debug!("searching {} candidates", kind);
1249 let res = self.consider_candidates(
1250 self_ty,
9c376795 1251 candidates,
0531ce1d 1252 &mut possibly_unsatisfied_predicates,
487cf647 1253 Some(&mut vec![]),
0531ce1d 1254 );
487cf647
FG
1255 if res.is_some() {
1256 return res;
0531ce1d 1257 }
1a4d82fc
JJ
1258 }
1259
9c376795
FG
1260 for (kind, candidates) in
1261 &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
1262 {
1263 debug!("searching unstable {kind} candidates");
1264 let res = self.consider_candidates(
1265 self_ty,
1266 candidates,
1267 &mut possibly_unsatisfied_predicates,
1268 None,
1269 );
1270 if res.is_some() {
1271 return res;
1272 }
62682a34 1273 }
9c376795
FG
1274
1275 self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates);
1276 None
1a4d82fc
JJ
1277 }
1278
3c0e092e 1279 fn pick_method(
9c376795 1280 &self,
3c0e092e
XL
1281 self_ty: Ty<'tcx>,
1282 mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
1283 ) -> Option<PickResult<'tcx>> {
064997fb 1284 if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable {
3c0e092e
XL
1285 return self.pick_method_with_unstable(self_ty);
1286 }
1287
1288 debug!("pick_method(self_ty={})", self.ty_to_string(self_ty));
1289
1290 let mut possibly_unsatisfied_predicates = Vec::new();
1291
1292 for (kind, candidates) in
1293 &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)]
1294 {
1295 debug!("searching {} candidates", kind);
1296 let res = self.consider_candidates(
1297 self_ty,
9c376795 1298 candidates,
3c0e092e
XL
1299 &mut possibly_unsatisfied_predicates,
1300 unstable_candidates.as_deref_mut(),
1301 );
1302 if let Some(pick) = res {
1303 return Some(pick);
1304 }
1305 }
1306
1307 // `pick_method` may be called twice for the same self_ty if no stable methods
1308 // match. Only extend once.
1309 if unstable_candidates.is_some() {
9c376795 1310 self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates);
3c0e092e
XL
1311 }
1312 None
1313 }
1314
9c376795 1315 fn consider_candidates(
0531ce1d
XL
1316 &self,
1317 self_ty: Ty<'tcx>,
9c376795 1318 candidates: &[Candidate<'tcx>],
74b04a01
XL
1319 possibly_unsatisfied_predicates: &mut Vec<(
1320 ty::Predicate<'tcx>,
1321 Option<ty::Predicate<'tcx>>,
3c0e092e 1322 Option<ObligationCause<'tcx>>,
74b04a01 1323 )>,
487cf647 1324 mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
9c376795
FG
1325 ) -> Option<PickResult<'tcx>> {
1326 let mut applicable_candidates: Vec<_> = candidates
1327 .iter()
ea8adc8c
XL
1328 .map(|probe| {
1329 (probe, self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates))
1330 })
1331 .filter(|&(_, status)| status != ProbeResult::NoMatch)
c30ab7b3 1332 .collect();
1a4d82fc 1333
62682a34 1334 debug!("applicable_candidates: {:?}", applicable_candidates);
1a4d82fc
JJ
1335
1336 if applicable_candidates.len() > 1 {
3c0e092e 1337 if let Some(pick) =
a2a8927a 1338 self.collapse_candidates_to_trait_pick(self_ty, &applicable_candidates)
3c0e092e 1339 {
ea8adc8c 1340 return Some(Ok(pick));
1a4d82fc
JJ
1341 }
1342 }
1343
487cf647 1344 if let Some(uc) = &mut unstable_candidates {
9c376795 1345 applicable_candidates.retain(|&(candidate, _)| {
0531ce1d 1346 if let stability::EvalResult::Deny { feature, .. } =
9c376795 1347 self.tcx.eval_stability(candidate.item.def_id, None, self.span, None)
0531ce1d 1348 {
9c376795 1349 uc.push((candidate.clone(), feature));
0531ce1d
XL
1350 return false;
1351 }
1352 true
1353 });
1354 }
1355
1a4d82fc 1356 if applicable_candidates.len() > 1 {
9c376795 1357 let sources = candidates.iter().map(|p| self.candidate_source(p, self_ty)).collect();
85aaf69f 1358 return Some(Err(MethodError::Ambiguity(sources)));
1a4d82fc
JJ
1359 }
1360
ea8adc8c
XL
1361 applicable_candidates.pop().map(|(probe, status)| {
1362 if status == ProbeResult::Match {
487cf647
FG
1363 Ok(probe
1364 .to_unadjusted_pick(self_ty, unstable_candidates.cloned().unwrap_or_default()))
ea8adc8c
XL
1365 } else {
1366 Err(MethodError::BadReturnType)
1367 }
1368 })
1369 }
487cf647
FG
1370}
1371
1372impl<'tcx> Pick<'tcx> {
1373 /// In case there were unstable name collisions, emit them as a lint.
1374 /// Checks whether two picks do not refer to the same trait item for the same `Self` type.
1375 /// Only useful for comparisons of picks in order to improve diagnostics.
1376 /// Do not use for type checking.
1377 pub fn differs_from(&self, other: &Self) -> bool {
1378 let Self {
1379 item:
1380 AssocItem {
1381 def_id,
1382 name: _,
1383 kind: _,
1384 container: _,
1385 trait_item_def_id: _,
1386 fn_has_self_parameter: _,
1387 },
1388 kind: _,
1389 import_ids: _,
1390 autoderefs: _,
1391 autoref_or_ptr_adjustment: _,
1392 self_ty,
1393 unstable_candidates: _,
1394 } = *self;
1395 self_ty != other.self_ty || def_id != other.item.def_id
1396 }
ea8adc8c 1397
487cf647
FG
1398 /// In case there were unstable name collisions, emit them as a lint.
1399 pub fn maybe_emit_unstable_name_collision_hint(
0531ce1d 1400 &self,
487cf647
FG
1401 tcx: TyCtxt<'tcx>,
1402 span: Span,
1403 scope_expr_id: hir::HirId,
0531ce1d 1404 ) {
487cf647
FG
1405 if self.unstable_candidates.is_empty() {
1406 return;
1407 }
1408 let def_kind = self.item.kind.as_def_kind();
1409 tcx.struct_span_lint_hir(
83c7162d 1410 lint::builtin::UNSTABLE_NAME_COLLISIONS,
487cf647
FG
1411 scope_expr_id,
1412 span,
2b03887a
FG
1413 format!(
1414 "{} {} with this name may be added to the standard library in the future",
1415 def_kind.article(),
487cf647 1416 def_kind.descr(self.item.def_id),
2b03887a 1417 ),
74b04a01 1418 |lint| {
487cf647 1419 match (self.item.kind, self.item.container) {
6a06907d
XL
1420 (ty::AssocKind::Fn, _) => {
1421 // FIXME: This should be a `span_suggestion` instead of `help`
1422 // However `self.span` only
1423 // highlights the method name, so we can't use it. Also consider reusing
1424 // the code from `report_method_error()`.
2b03887a 1425 lint.help(&format!(
6a06907d
XL
1426 "call with fully qualified syntax `{}(...)` to keep using the current \
1427 method",
487cf647 1428 tcx.def_path_str(self.item.def_id),
6a06907d
XL
1429 ));
1430 }
064997fb 1431 (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
487cf647 1432 let def_id = self.item.container_id(tcx);
2b03887a 1433 lint.span_suggestion(
487cf647 1434 span,
6a06907d
XL
1435 "use the fully qualified path to the associated const",
1436 format!(
1437 "<{} as {}>::{}",
487cf647
FG
1438 self.self_ty,
1439 tcx.def_path_str(def_id),
1440 self.item.name
6a06907d
XL
1441 ),
1442 Applicability::MachineApplicable,
1443 );
1444 }
1445 _ => {}
1446 }
487cf647
FG
1447 if tcx.sess.is_nightly_build() {
1448 for (candidate, feature) in &self.unstable_candidates {
2b03887a 1449 lint.help(&format!(
74b04a01
XL
1450 "add `#![feature({})]` to the crate attributes to enable `{}`",
1451 feature,
487cf647 1452 tcx.def_path_str(candidate.item.def_id),
74b04a01
XL
1453 ));
1454 }
1455 }
1456
2b03887a 1457 lint
74b04a01
XL
1458 },
1459 );
0531ce1d 1460 }
487cf647 1461}
0531ce1d 1462
487cf647 1463impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
dfeec247
XL
1464 fn select_trait_candidate(
1465 &self,
1466 trait_ref: ty::TraitRef<'tcx>,
1467 ) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> {
ea8adc8c 1468 let cause = traits::ObligationCause::misc(self.span, self.body_id);
487cf647
FG
1469 let predicate = ty::Binder::dummy(trait_ref);
1470 let obligation = traits::Obligation::new(self.tcx, cause, self.param_env, predicate);
ea8adc8c
XL
1471 traits::SelectionContext::new(self).select(&obligation)
1472 }
1473
dfeec247 1474 fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource {
ea8adc8c 1475 match candidate.kind {
064997fb
FG
1476 InherentImplCandidate(..) => {
1477 CandidateSource::Impl(candidate.item.container_id(self.tcx))
1478 }
04454e1e 1479 ObjectCandidate | WhereClauseCandidate(_) => {
064997fb 1480 CandidateSource::Trait(candidate.item.container_id(self.tcx))
04454e1e 1481 }
ea8adc8c 1482 TraitCandidate(trait_ref) => self.probe(|_| {
dfeec247
XL
1483 let _ = self
1484 .at(&ObligationCause::dummy(), self.param_env)
5e7ed085 1485 .define_opaque_types(false)
ea8adc8c
XL
1486 .sup(candidate.xform_self_ty, self_ty);
1487 match self.select_trait_candidate(trait_ref) {
1b1a35ee 1488 Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => {
ea8adc8c
XL
1489 // If only a single impl matches, make the error message point
1490 // to that impl.
04454e1e 1491 CandidateSource::Impl(impl_data.impl_def_id)
ea8adc8c 1492 }
064997fb 1493 _ => CandidateSource::Trait(candidate.item.container_id(self.tcx)),
ea8adc8c 1494 }
dfeec247 1495 }),
ea8adc8c 1496 }
1a4d82fc
JJ
1497 }
1498
dfeec247
XL
1499 fn consider_probe(
1500 &self,
1501 self_ty: Ty<'tcx>,
1502 probe: &Candidate<'tcx>,
74b04a01
XL
1503 possibly_unsatisfied_predicates: &mut Vec<(
1504 ty::Predicate<'tcx>,
1505 Option<ty::Predicate<'tcx>>,
3c0e092e 1506 Option<ObligationCause<'tcx>>,
74b04a01 1507 )>,
dfeec247 1508 ) -> ProbeResult {
c30ab7b3 1509 debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe);
1a4d82fc 1510
a7813a04 1511 self.probe(|_| {
1a4d82fc 1512 // First check that the self type can be related.
dfeec247
XL
1513 let sub_obligations = match self
1514 .at(&ObligationCause::dummy(), self.param_env)
5e7ed085 1515 .define_opaque_types(false)
dfeec247
XL
1516 .sup(probe.xform_self_ty, self_ty)
1517 {
cc61c64b 1518 Ok(InferOk { obligations, value: () }) => obligations,
3c0e092e
XL
1519 Err(err) => {
1520 debug!("--> cannot relate self-types {:?}", err);
ea8adc8c 1521 return ProbeResult::NoMatch;
1a4d82fc 1522 }
cc61c64b 1523 };
1a4d82fc 1524
ea8adc8c 1525 let mut result = ProbeResult::Match;
c295e0f8
XL
1526 let mut xform_ret_ty = probe.xform_ret_ty;
1527 debug!(?xform_ret_ty);
1528
ea8adc8c
XL
1529 let cause = traits::ObligationCause::misc(self.span, self.body_id);
1530
5e7ed085
FG
1531 let mut parent_pred = None;
1532
1a4d82fc
JJ
1533 // If so, impls may carry other conditions (e.g., where
1534 // clauses) that must be considered. Make sure that those
1535 // match as well (or at least may match, sometimes we
1536 // don't have enough information to fully evaluate).
ba9703b0 1537 match probe.kind {
c1a9b12d 1538 InherentImplCandidate(ref substs, ref ref_obligations) => {
c295e0f8
XL
1539 // `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
1540 // see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
1541 // for why this is necessary
487cf647 1542 let InferOk {
c295e0f8
XL
1543 value: normalized_xform_ret_ty,
1544 obligations: normalization_obligations,
9c376795 1545 } = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
c295e0f8
XL
1546 xform_ret_ty = normalized_xform_ret_ty;
1547 debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
1548
ea8adc8c 1549 // Check whether the impl imposes obligations we have to worry about.
064997fb 1550 let impl_def_id = probe.item.container_id(self.tcx);
ea8adc8c
XL
1551 let impl_bounds = self.tcx.predicates_of(impl_def_id);
1552 let impl_bounds = impl_bounds.instantiate(self.tcx, substs);
487cf647
FG
1553
1554 let InferOk { value: impl_bounds, obligations: norm_obligations } =
1555 self.fcx.at(&cause, self.param_env).normalize(impl_bounds);
ea8adc8c
XL
1556
1557 // Convert the bounds into obligations.
f2b60f7d 1558 let impl_obligations = traits::predicates_for_generics(
9c376795
FG
1559 |_idx, span| {
1560 let misc = traits::ObligationCause::misc(span, self.body_id);
1561 let parent_trait_pred = ty::Binder::dummy(ty::TraitPredicate {
1562 trait_ref: ty::TraitRef::from_method(self.tcx, impl_def_id, substs),
1563 constness: ty::BoundConstness::NotConst,
1564 polarity: ty::ImplPolarity::Positive,
1565 });
1566 misc.derived_cause(parent_trait_pred, |derived| {
1567 traits::ImplDerivedObligation(Box::new(
1568 traits::ImplDerivedObligationCause {
1569 derived,
1570 impl_def_id,
1571 span,
1572 },
1573 ))
1574 })
1575 },
f2b60f7d
FG
1576 self.param_env,
1577 impl_bounds,
1578 );
ea8adc8c 1579
ba9703b0 1580 let candidate_obligations = impl_obligations
ea8adc8c 1581 .chain(norm_obligations.into_iter())
c295e0f8
XL
1582 .chain(ref_obligations.iter().cloned())
1583 .chain(normalization_obligations.into_iter());
1584
ba9703b0
XL
1585 // Evaluate those obligations to see if they might possibly hold.
1586 for o in candidate_obligations {
fc512014 1587 let o = self.resolve_vars_if_possible(o);
ba9703b0
XL
1588 if !self.predicate_may_hold(&o) {
1589 result = ProbeResult::NoMatch;
9c376795
FG
1590 let parent_o = o.clone();
1591 let implied_obligations =
1592 traits::elaborate_obligations(self.tcx, vec![o]);
1593 for o in implied_obligations {
1594 let parent = if o == parent_o {
1595 None
1596 } else {
1597 if o.predicate.to_opt_poly_trait_pred().map(|p| p.def_id())
1598 == self.tcx.lang_items().sized_trait()
1599 {
1600 // We don't care to talk about implicit `Sized` bounds.
1601 continue;
1602 }
1603 Some(parent_o.predicate)
1604 };
1605 if !self.predicate_may_hold(&o) {
1606 possibly_unsatisfied_predicates.push((
1607 o.predicate,
1608 parent,
1609 Some(o.cause),
1610 ));
1611 }
1612 }
ba9703b0
XL
1613 }
1614 }
1a4d82fc
JJ
1615 }
1616
dfeec247 1617 ObjectCandidate | WhereClauseCandidate(..) => {
1a4d82fc 1618 // These have no additional conditions to check.
c1a9b12d 1619 }
c1a9b12d 1620
ea8adc8c 1621 TraitCandidate(trait_ref) => {
cdc7bbd5
XL
1622 if let Some(method_name) = self.method_name {
1623 // Some trait methods are excluded for arrays before 2021.
1624 // (`array.into_iter()` wants a slice iterator for compatibility.)
1625 if self_ty.is_array() && !method_name.span.rust_2021() {
1626 let trait_def = self.tcx.trait_def(trait_ref.def_id);
1627 if trait_def.skip_array_during_method_dispatch {
1628 return ProbeResult::NoMatch;
1629 }
1630 }
1631 }
c295e0f8
XL
1632 let predicate =
1633 ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx);
5e7ed085 1634 parent_pred = Some(predicate);
487cf647 1635 let obligation =
9c376795 1636 traits::Obligation::new(self.tcx, cause.clone(), self.param_env, predicate);
83c7162d 1637 if !self.predicate_may_hold(&obligation) {
74b04a01
XL
1638 result = ProbeResult::NoMatch;
1639 if self.probe(|_| {
1640 match self.select_trait_candidate(trait_ref) {
1641 Err(_) => return true,
f035d41b
XL
1642 Ok(Some(impl_source))
1643 if !impl_source.borrow_nested_obligations().is_empty() =>
74b04a01 1644 {
f035d41b 1645 for obligation in impl_source.borrow_nested_obligations() {
74b04a01
XL
1646 // Determine exactly which obligation wasn't met, so
1647 // that we can give more context in the error.
fc512014
XL
1648 if !self.predicate_may_hold(obligation) {
1649 let nested_predicate =
1650 self.resolve_vars_if_possible(obligation.predicate);
74b04a01 1651 let predicate =
fc512014
XL
1652 self.resolve_vars_if_possible(predicate);
1653 let p = if predicate == nested_predicate {
74b04a01
XL
1654 // Avoid "`MyStruct: Foo` which is required by
1655 // `MyStruct: Foo`" in E0599.
1656 None
1657 } else {
1658 Some(predicate)
1659 };
3c0e092e
XL
1660 possibly_unsatisfied_predicates.push((
1661 nested_predicate,
1662 p,
1663 Some(obligation.cause.clone()),
1664 ));
74b04a01
XL
1665 }
1666 }
1667 }
1668 _ => {
1669 // Some nested subobligation of this predicate
1670 // failed.
fc512014 1671 let predicate = self.resolve_vars_if_possible(predicate);
3c0e092e 1672 possibly_unsatisfied_predicates.push((predicate, None, None));
74b04a01
XL
1673 }
1674 }
1675 false
1676 }) {
ea8adc8c
XL
1677 // This candidate's primary obligation doesn't even
1678 // select - don't bother registering anything in
1679 // `potentially_unsatisfied_predicates`.
1680 return ProbeResult::NoMatch;
ea8adc8c
XL
1681 }
1682 }
ea8adc8c 1683 }
ba9703b0 1684 }
c1a9b12d
SL
1685
1686 // Evaluate those obligations to see if they might possibly hold.
ba9703b0 1687 for o in sub_obligations {
fc512014 1688 let o = self.resolve_vars_if_possible(o);
83c7162d 1689 if !self.predicate_may_hold(&o) {
ea8adc8c 1690 result = ProbeResult::NoMatch;
5e7ed085 1691 possibly_unsatisfied_predicates.push((o.predicate, parent_pred, Some(o.cause)));
1a4d82fc
JJ
1692 }
1693 }
ea8adc8c 1694
9c376795
FG
1695 if let ProbeResult::Match = result
1696 && let Some(return_ty) = self.return_type
1697 && let Some(mut xform_ret_ty) = xform_ret_ty
1698 {
1699 // `xform_ret_ty` has only been normalized for `InherentImplCandidate`.
1700 // We don't normalize the other candidates for perf/backwards-compat reasons...
1701 // but `self.return_type` is only set on the diagnostic-path, so we
1702 // should be okay doing it here.
1703 if !matches!(probe.kind, InherentImplCandidate(..)) {
1704 let InferOk {
1705 value: normalized_xform_ret_ty,
1706 obligations: normalization_obligations,
1707 } = self.fcx.at(&cause, self.param_env).normalize(xform_ret_ty);
1708 xform_ret_ty = normalized_xform_ret_ty;
1709 debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
1710 // Evaluate those obligations to see if they might possibly hold.
1711 for o in normalization_obligations {
1712 let o = self.resolve_vars_if_possible(o);
1713 if !self.predicate_may_hold(&o) {
1714 result = ProbeResult::NoMatch;
1715 possibly_unsatisfied_predicates.push((
1716 o.predicate,
1717 None,
1718 Some(o.cause),
1719 ));
1720 }
ea8adc8c
XL
1721 }
1722 }
9c376795
FG
1723
1724 debug!(
1725 "comparing return_ty {:?} with xform ret ty {:?}",
1726 return_ty, xform_ret_ty
1727 );
1728 if let ProbeResult::Match = result
1729 && self
1730 .at(&ObligationCause::dummy(), self.param_env)
1731 .define_opaque_types(false)
1732 .sup(return_ty, xform_ret_ty)
1733 .is_err()
1734 {
1735 result = ProbeResult::BadReturnType;
1736 }
ea8adc8c
XL
1737 }
1738
1739 result
1a4d82fc
JJ
1740 })
1741 }
1742
1743 /// Sometimes we get in a situation where we have multiple probes that are all impls of the
1744 /// same trait, but we don't know which impl to use. In this case, since in all cases the
1745 /// external interface of the method can be determined from the trait, it's ok not to decide.
1746 /// We can basically just collapse all of the probes for various impls into one where-clause
1747 /// probe. This will result in a pending obligation so when more type-info is available we can
1748 /// make the final decision.
1749 ///
9c376795 1750 /// Example (`tests/ui/method-two-trait-defer-resolution-1.rs`):
1a4d82fc 1751 ///
04454e1e 1752 /// ```ignore (illustrative)
1a4d82fc 1753 /// trait Foo { ... }
f035d41b 1754 /// impl Foo for Vec<i32> { ... }
c34b1796 1755 /// impl Foo for Vec<usize> { ... }
1a4d82fc
JJ
1756 /// ```
1757 ///
1758 /// Now imagine the receiver is `Vec<_>`. It doesn't really matter at this time which impl we
1759 /// use, so it's ok to just commit to "using the method from the trait Foo".
dfeec247
XL
1760 fn collapse_candidates_to_trait_pick(
1761 &self,
3c0e092e 1762 self_ty: Ty<'tcx>,
dfeec247
XL
1763 probes: &[(&Candidate<'tcx>, ProbeResult)],
1764 ) -> Option<Pick<'tcx>> {
1a4d82fc 1765 // Do all probes correspond to the same trait?
064997fb
FG
1766 let container = probes[0].0.item.trait_container(self.tcx)?;
1767 for (p, _) in &probes[1..] {
1768 let p_container = p.item.trait_container(self.tcx)?;
1769 if p_container != container {
1770 return None;
1771 }
1a4d82fc
JJ
1772 }
1773
ea8adc8c 1774 // FIXME: check the return type here somehow.
1a4d82fc 1775 // If so, just use this trait and call it a day.
1a4d82fc 1776 Some(Pick {
dfeec247 1777 item: probes[0].0.item,
c1a9b12d 1778 kind: TraitPick,
48663c56 1779 import_ids: probes[0].0.import_ids.clone(),
9346a6ac 1780 autoderefs: 0,
6a06907d 1781 autoref_or_ptr_adjustment: None,
3c0e092e 1782 self_ty,
487cf647 1783 unstable_candidates: vec![],
1a4d82fc
JJ
1784 })
1785 }
1786
ea8adc8c 1787 /// Similarly to `probe_for_return_type`, this method attempts to find the best matching
5e7ed085 1788 /// candidate method where the method name may have been misspelled. Similarly to other
ea8adc8c 1789 /// Levenshtein based suggestions, we provide at most one such suggestion.
dc9dc135 1790 fn probe_for_lev_candidate(&mut self) -> Result<Option<ty::AssocItem>, MethodError<'tcx>> {
dfeec247 1791 debug!("probing for method names similar to {:?}", self.method_name);
ea8adc8c
XL
1792
1793 let steps = self.steps.clone();
1794 self.probe(|_| {
dfeec247
XL
1795 let mut pcx = ProbeContext::new(
1796 self.fcx,
1797 self.span,
1798 self.mode,
1799 self.method_name,
1800 self.return_type,
9c376795 1801 &self.orig_steps_var_values,
dfeec247 1802 steps,
cdc7bbd5 1803 self.scope_expr_id,
dfeec247 1804 );
ea8adc8c
XL
1805 pcx.allow_similar_names = true;
1806 pcx.assemble_inherent_candidates();
ea8adc8c 1807
2b03887a 1808 let method_names = pcx.candidate_method_names(|_| true);
ea8adc8c 1809 pcx.allow_similar_names = false;
74b04a01
XL
1810 let applicable_close_candidates: Vec<ty::AssocItem> = method_names
1811 .iter()
1812 .filter_map(|&method_name| {
1813 pcx.reset();
1814 pcx.method_name = Some(method_name);
1815 pcx.assemble_inherent_candidates();
ba9703b0 1816 pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item)
74b04a01
XL
1817 })
1818 .collect();
ea8adc8c
XL
1819
1820 if applicable_close_candidates.is_empty() {
1821 Ok(None)
1822 } else {
1823 let best_name = {
fc512014
XL
1824 let names = applicable_close_candidates
1825 .iter()
5099ac24 1826 .map(|cand| cand.name)
fc512014 1827 .collect::<Vec<Symbol>>();
04454e1e
FG
1828 find_best_match_for_name_with_substrings(
1829 &names,
1830 self.method_name.unwrap().name,
1831 None,
1832 )
dfeec247
XL
1833 }
1834 .unwrap();
5099ac24 1835 Ok(applicable_close_candidates.into_iter().find(|method| method.name == best_name))
ea8adc8c
XL
1836 }
1837 })
1838 }
1839
1a4d82fc
JJ
1840 ///////////////////////////////////////////////////////////////////////////
1841 // MISCELLANY
dc9dc135 1842 fn has_applicable_self(&self, item: &ty::AssocItem) -> bool {
476ff2be
SL
1843 // "Fast track" -- check for usage of sugar when in method call
1844 // mode.
1845 //
1846 // In Path mode (i.e., resolving a value like `T::next`), consider any
1847 // associated value (i.e., methods, constants) but not types.
1848 match self.mode {
ba9703b0 1849 Mode::MethodCall => item.fn_has_self_parameter,
476ff2be 1850 Mode::Path => match item.kind {
f035d41b 1851 ty::AssocKind::Type => false,
ba9703b0 1852 ty::AssocKind::Fn | ty::AssocKind::Const => true,
476ff2be 1853 },
1a4d82fc 1854 }
1a4d82fc
JJ
1855 // FIXME -- check for types that deref to `Self`,
1856 // like `Rc<Self>` and so on.
1857 //
1858 // Note also that the current code will break if this type
1859 // includes any of the type parameters defined on the method
1860 // -- but this could be overcome.
1a4d82fc
JJ
1861 }
1862
9c376795
FG
1863 fn record_static_candidate(&self, source: CandidateSource) {
1864 self.static_candidates.borrow_mut().push(source);
1a4d82fc
JJ
1865 }
1866
c295e0f8 1867 #[instrument(level = "debug", skip(self))]
dfeec247
XL
1868 fn xform_self_ty(
1869 &self,
1870 item: &ty::AssocItem,
1871 impl_ty: Ty<'tcx>,
1872 substs: SubstsRef<'tcx>,
1873 ) -> (Ty<'tcx>, Option<Ty<'tcx>>) {
ba9703b0 1874 if item.kind == ty::AssocKind::Fn && self.mode == Mode::MethodCall {
ea8adc8c
XL
1875 let sig = self.xform_method_sig(item.def_id, substs);
1876 (sig.inputs()[0], Some(sig.output()))
476ff2be 1877 } else {
ea8adc8c 1878 (impl_ty, None)
d9579d0f
AL
1879 }
1880 }
1881
c295e0f8 1882 #[instrument(level = "debug", skip(self))]
dfeec247 1883 fn xform_method_sig(&self, method: DefId, substs: SubstsRef<'tcx>) -> ty::FnSig<'tcx> {
04454e1e 1884 let fn_sig = self.tcx.bound_fn_sig(method);
c295e0f8 1885 debug!(?fn_sig);
1a4d82fc 1886
a1dfa0c6 1887 assert!(!substs.has_escaping_bound_vars());
1a4d82fc
JJ
1888
1889 // It is possible for type parameters or early-bound lifetimes
1890 // to appear in the signature of `self`. The substitutions we
1891 // are given do not include type/lifetime parameters for the
1892 // method yet. So create fresh variables here for those too,
1893 // if there are any.
7cac9316 1894 let generics = self.tcx.generics_of(method);
94b46f34 1895 assert_eq!(substs.len(), generics.parent_count as usize);
c34b1796 1896
04454e1e
FG
1897 let xform_fn_sig = if generics.params.is_empty() {
1898 fn_sig.subst(self.tcx, substs)
9e0c209e 1899 } else {
532ac7d7 1900 let substs = InternalSubsts::for_item(self.tcx, method, |param, _| {
94b46f34 1901 let i = param.index as usize;
8bb4bdeb 1902 if i < substs.len() {
94b46f34 1903 substs[i]
9e0c209e 1904 } else {
94b46f34
XL
1905 match param.kind {
1906 GenericParamDefKind::Lifetime => {
ba9703b0 1907 // In general, during probe we erase regions.
48663c56 1908 self.tcx.lifetimes.re_erased.into()
94b46f34 1909 }
cdc7bbd5 1910 GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
532ac7d7
XL
1911 self.var_for_def(self.span, param)
1912 }
94b46f34 1913 }
9e0c209e
SL
1914 }
1915 });
04454e1e
FG
1916 fn_sig.subst(self.tcx, substs)
1917 };
1918
1919 self.erase_late_bound_regions(xform_fn_sig)
1a4d82fc
JJ
1920 }
1921
064997fb
FG
1922 /// Gets the type of an impl and generate substitutions with inference vars.
1923 fn impl_ty_and_substs(
1924 &self,
1925 impl_def_id: DefId,
1926 ) -> (ty::EarlyBinder<Ty<'tcx>>, SubstsRef<'tcx>) {
1927 (self.tcx.bound_type_of(impl_def_id), self.fresh_item_substs(impl_def_id))
ea8adc8c 1928 }
1a4d82fc 1929
532ac7d7 1930 fn fresh_item_substs(&self, def_id: DefId) -> SubstsRef<'tcx> {
dfeec247
XL
1931 InternalSubsts::for_item(self.tcx, def_id, |param, _| match param.kind {
1932 GenericParamDefKind::Lifetime => self.tcx.lifetimes.re_erased.into(),
1933 GenericParamDefKind::Type { .. } => self
1934 .next_ty_var(TypeVariableOrigin {
1935 kind: TypeVariableOriginKind::SubstitutionPlaceholder,
1936 span: self.tcx.def_span(def_id),
1937 })
1938 .into(),
1939 GenericParamDefKind::Const { .. } => {
1940 let span = self.tcx.def_span(def_id);
1941 let origin = ConstVariableOrigin {
1942 kind: ConstVariableOriginKind::SubstitutionPlaceholder,
1943 span,
1944 };
1945 self.next_const_var(self.tcx.type_of(param.def_id), origin).into()
94b46f34
XL
1946 }
1947 })
1a4d82fc
JJ
1948 }
1949
9fa01778 1950 /// Replaces late-bound-regions bound by `value` with `'static` using
1a4d82fc
JJ
1951 /// `ty::erase_late_bound_regions`.
1952 ///
1953 /// This is only a reasonable thing to do during the *probe* phase, not the *confirm* phase, of
1954 /// method matching. It is reasonable during the probe phase because we don't consider region
1955 /// relationships at all. Therefore, we can just replace all the region variables with 'static
1956 /// rather than creating fresh region variables. This is nice for two reasons:
1957 ///
1958 /// 1. Because the numbers of the region variables would otherwise be fairly unique to this
1959 /// particular method call, it winds up creating fewer types overall, which helps for memory
a1dfa0c6 1960 /// usage. (Admittedly, this is a rather small effect, though measurable.)
1a4d82fc
JJ
1961 ///
1962 /// 2. It makes it easier to deal with higher-ranked trait bounds, because we can replace any
1963 /// late-bound regions with 'static. Otherwise, if we were going to replace late-bound
1964 /// regions with actual region variables as is proper, we'd have to ensure that the same
1965 /// region got replaced with the same variable, which requires a bit more coordination
1966 /// and/or tracking the substitution and
1967 /// so forth.
cdc7bbd5 1968 fn erase_late_bound_regions<T>(&self, value: ty::Binder<'tcx, T>) -> T
dfeec247
XL
1969 where
1970 T: TypeFoldable<'tcx>,
1a4d82fc 1971 {
a7813a04 1972 self.tcx.erase_late_bound_regions(value)
1a4d82fc 1973 }
1a4d82fc 1974
487cf647
FG
1975 /// Determine if the given associated item type is relevant in the current context.
1976 fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool {
1977 match (self.mode, kind) {
1978 (Mode::MethodCall, ty::AssocKind::Fn) => true,
1979 (Mode::Path, ty::AssocKind::Const | ty::AssocKind::Fn) => true,
1980 _ => false,
1981 }
1982 }
1983
9fa01778 1984 /// Finds the method with the appropriate name (or return type, as the case may be). If
ea8adc8c 1985 /// `allow_similar_names` is set, find methods with close-matching names.
cdc7bbd5
XL
1986 // The length of the returned iterator is nearly always 0 or 1 and this
1987 // method is fairly hot.
1988 fn impl_or_trait_item(&self, def_id: DefId) -> SmallVec<[ty::AssocItem; 1]> {
ea8adc8c
XL
1989 if let Some(name) = self.method_name {
1990 if self.allow_similar_names {
1991 let max_dist = max(name.as_str().len(), 3) / 3;
dfeec247
XL
1992 self.tcx
1993 .associated_items(def_id)
74b04a01 1994 .in_definition_order()
ea8adc8c 1995 .filter(|x| {
487cf647 1996 if !self.is_relevant_kind_for_mode(x.kind) {
5099ac24
FG
1997 return false;
1998 }
04454e1e
FG
1999 match lev_distance_with_substrings(name.as_str(), x.name.as_str(), max_dist)
2000 {
5099ac24
FG
2001 Some(d) => d > 0,
2002 None => false,
2003 }
ea8adc8c 2004 })
74b04a01 2005 .copied()
32a655c1 2006 .collect()
ea8adc8c 2007 } else {
abe05a73 2008 self.fcx
5099ac24 2009 .associated_value(def_id, name)
487cf647 2010 .filter(|x| self.is_relevant_kind_for_mode(x.kind))
cdc7bbd5 2011 .map_or_else(SmallVec::new, |x| SmallVec::from_buf([x]))
32a655c1 2012 }
ea8adc8c 2013 } else {
487cf647
FG
2014 self.tcx
2015 .associated_items(def_id)
2016 .in_definition_order()
2017 .filter(|x| self.is_relevant_kind_for_mode(x.kind))
2018 .copied()
2019 .collect()
32a655c1 2020 }
a7813a04 2021 }
1a4d82fc
JJ
2022}
2023
2024impl<'tcx> Candidate<'tcx> {
487cf647
FG
2025 fn to_unadjusted_pick(
2026 &self,
2027 self_ty: Ty<'tcx>,
2028 unstable_candidates: Vec<(Candidate<'tcx>, Symbol)>,
2029 ) -> Pick<'tcx> {
1a4d82fc 2030 Pick {
dfeec247 2031 item: self.item,
1a4d82fc 2032 kind: match self.kind {
9e0c209e 2033 InherentImplCandidate(..) => InherentImplPick,
c1a9b12d 2034 ObjectCandidate => ObjectPick,
ea8adc8c 2035 TraitCandidate(_) => TraitPick,
c1a9b12d 2036 WhereClauseCandidate(ref trait_ref) => {
1a4d82fc
JJ
2037 // Only trait derived from where-clauses should
2038 // appear here, so they should not contain any
2039 // inference variables or other artifacts. This
2040 // means they are safe to put into the
2041 // `WhereClausePick`.
83c7162d
XL
2042 assert!(
2043 !trait_ref.skip_binder().substs.needs_infer()
a1dfa0c6 2044 && !trait_ref.skip_binder().substs.has_placeholders()
83c7162d 2045 );
1a4d82fc 2046
dfeec247 2047 WhereClausePick(*trait_ref)
1a4d82fc 2048 }
9346a6ac 2049 },
48663c56 2050 import_ids: self.import_ids.clone(),
9346a6ac 2051 autoderefs: 0,
6a06907d 2052 autoref_or_ptr_adjustment: None,
3c0e092e 2053 self_ty,
487cf647 2054 unstable_candidates,
1a4d82fc
JJ
2055 }
2056 }
1a4d82fc 2057}