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