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