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