]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/method/probe.rs
88bd000cfdd65340fb1907a907e84fe4680030f5
[rust.git] / src / librustc_typeck / check / method / probe.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use super::MethodError;
12 use super::NoMatchData;
13 use super::{CandidateSource, ImplSource, TraitSource};
14 use super::suggest;
15
16 use check;
17 use check::{FnCtxt, NoPreference, UnresolvedTypeAction};
18 use middle::fast_reject;
19 use middle::subst;
20 use middle::subst::Subst;
21 use middle::traits;
22 use middle::ty::{self, RegionEscape, Ty, ToPolyTraitRef, TraitRef};
23 use middle::ty::HasTypeFlags;
24 use middle::ty_fold::TypeFoldable;
25 use middle::infer;
26 use middle::infer::InferCtxt;
27 use syntax::ast;
28 use syntax::codemap::{Span, DUMMY_SP};
29 use std::collections::HashSet;
30 use std::mem;
31 use std::rc::Rc;
32
33 use self::CandidateKind::*;
34 pub use self::PickKind::*;
35
36 struct ProbeContext<'a, 'tcx:'a> {
37     fcx: &'a FnCtxt<'a, 'tcx>,
38     span: Span,
39     mode: Mode,
40     item_name: ast::Name,
41     steps: Rc<Vec<CandidateStep<'tcx>>>,
42     opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>,
43     inherent_candidates: Vec<Candidate<'tcx>>,
44     extension_candidates: Vec<Candidate<'tcx>>,
45     impl_dups: HashSet<ast::DefId>,
46
47     /// Collects near misses when the candidate functions are missing a `self` keyword and is only
48     /// used for error reporting
49     static_candidates: Vec<CandidateSource>,
50
51     /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
52     /// for error reporting
53     unsatisfied_predicates: Vec<TraitRef<'tcx>>
54 }
55
56 #[derive(Debug)]
57 struct CandidateStep<'tcx> {
58     self_ty: Ty<'tcx>,
59     autoderefs: usize,
60     unsize: bool
61 }
62
63 #[derive(Debug)]
64 struct Candidate<'tcx> {
65     xform_self_ty: Ty<'tcx>,
66     item: ty::ImplOrTraitItem<'tcx>,
67     kind: CandidateKind<'tcx>,
68 }
69
70 #[derive(Debug)]
71 enum CandidateKind<'tcx> {
72     InherentImplCandidate(subst::Substs<'tcx>,
73                           /* Normalize obligations */ Vec<traits::PredicateObligation<'tcx>>),
74     ExtensionImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>,
75                            /* Normalize obligations */ Vec<traits::PredicateObligation<'tcx>>),
76     ObjectCandidate,
77     TraitCandidate,
78     WhereClauseCandidate(/* Trait */ ty::PolyTraitRef<'tcx>),
79 }
80
81 #[derive(Debug)]
82 pub struct Pick<'tcx> {
83     pub item: ty::ImplOrTraitItem<'tcx>,
84     pub kind: PickKind<'tcx>,
85
86     // Indicates that the source expression should be autoderef'd N times
87     //
88     // A = expr | *expr | **expr | ...
89     pub autoderefs: usize,
90
91     // Indicates that an autoref is applied after the optional autoderefs
92     //
93     // B = A | &A | &mut A
94     pub autoref: Option<ast::Mutability>,
95
96     // Indicates that the source expression should be "unsized" to a
97     // target type. This should probably eventually go away in favor
98     // of just coercing method receivers.
99     //
100     // C = B | unsize(B)
101     pub unsize: Option<Ty<'tcx>>,
102 }
103
104 #[derive(Clone,Debug)]
105 pub enum PickKind<'tcx> {
106     InherentImplPick,
107     ExtensionImplPick(/* Impl */ ast::DefId),
108     ObjectPick,
109     TraitPick,
110     WhereClausePick(/* Trait */ ty::PolyTraitRef<'tcx>),
111 }
112
113 pub type PickResult<'tcx> = Result<Pick<'tcx>, MethodError<'tcx>>;
114
115 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
116 pub enum Mode {
117     // An expression of the form `receiver.method_name(...)`.
118     // Autoderefs are performed on `receiver`, lookup is done based on the
119     // `self` argument  of the method, and static methods aren't considered.
120     MethodCall,
121     // An expression of the form `Type::item` or `<T>::item`.
122     // No autoderefs are performed, lookup is done based on the type each
123     // implementation is for, and static methods are included.
124     Path
125 }
126
127 pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
128                        span: Span,
129                        mode: Mode,
130                        item_name: ast::Name,
131                        self_ty: Ty<'tcx>,
132                        scope_expr_id: ast::NodeId)
133                        -> PickResult<'tcx>
134 {
135     debug!("probe(self_ty={:?}, item_name={}, scope_expr_id={})",
136            self_ty,
137            item_name,
138            scope_expr_id);
139
140     // FIXME(#18741) -- right now, creating the steps involves evaluating the
141     // `*` operator, which registers obligations that then escape into
142     // the global fulfillment context and thus has global
143     // side-effects. This is a bit of a pain to refactor. So just let
144     // it ride, although it's really not great, and in fact could I
145     // think cause spurious errors. Really though this part should
146     // take place in the `fcx.infcx().probe` below.
147     let steps = if mode == Mode::MethodCall {
148         match create_steps(fcx, span, self_ty) {
149             Some(steps) => steps,
150             None =>return Err(MethodError::NoMatch(NoMatchData::new(Vec::new(), Vec::new(),
151                                                                     Vec::new(), mode))),
152         }
153     } else {
154         vec![CandidateStep {
155             self_ty: self_ty,
156             autoderefs: 0,
157             unsize: false
158         }]
159     };
160
161     // Create a list of simplified self types, if we can.
162     let mut simplified_steps = Vec::new();
163     for step in &steps {
164         match fast_reject::simplify_type(fcx.tcx(), step.self_ty, true) {
165             None => { break; }
166             Some(simplified_type) => { simplified_steps.push(simplified_type); }
167         }
168     }
169     let opt_simplified_steps =
170         if simplified_steps.len() < steps.len() {
171             None // failed to convert at least one of the steps
172         } else {
173             Some(simplified_steps)
174         };
175
176     debug!("ProbeContext: steps for self_ty={:?} are {:?}",
177            self_ty,
178            steps);
179
180     // this creates one big transaction so that all type variables etc
181     // that we create during the probe process are removed later
182     fcx.infcx().probe(|_| {
183         let mut probe_cx = ProbeContext::new(fcx,
184                                              span,
185                                              mode,
186                                              item_name,
187                                              steps,
188                                              opt_simplified_steps);
189         probe_cx.assemble_inherent_candidates();
190         try!(probe_cx.assemble_extension_candidates_for_traits_in_scope(scope_expr_id));
191         probe_cx.pick()
192     })
193 }
194
195 fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
196                           span: Span,
197                           self_ty: Ty<'tcx>)
198                           -> Option<Vec<CandidateStep<'tcx>>> {
199     let mut steps = Vec::new();
200
201     let (final_ty, dereferences, _) = check::autoderef(fcx,
202                                                        span,
203                                                        self_ty,
204                                                        None,
205                                                        UnresolvedTypeAction::Error,
206                                                        NoPreference,
207                                                        |t, d| {
208         steps.push(CandidateStep {
209             self_ty: t,
210             autoderefs: d,
211             unsize: false
212         });
213         None::<()> // keep iterating until we can't anymore
214     });
215
216     match final_ty.sty {
217         ty::TyArray(elem_ty, _) => {
218             steps.push(CandidateStep {
219                 self_ty: fcx.tcx().mk_slice(elem_ty),
220                 autoderefs: dereferences,
221                 unsize: true
222             });
223         }
224         ty::TyError => return None,
225         _ => (),
226     }
227
228     Some(steps)
229 }
230
231 impl<'a,'tcx> ProbeContext<'a,'tcx> {
232     fn new(fcx: &'a FnCtxt<'a,'tcx>,
233            span: Span,
234            mode: Mode,
235            item_name: ast::Name,
236            steps: Vec<CandidateStep<'tcx>>,
237            opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>)
238            -> ProbeContext<'a,'tcx>
239     {
240         ProbeContext {
241             fcx: fcx,
242             span: span,
243             mode: mode,
244             item_name: item_name,
245             inherent_candidates: Vec::new(),
246             extension_candidates: Vec::new(),
247             impl_dups: HashSet::new(),
248             steps: Rc::new(steps),
249             opt_simplified_steps: opt_simplified_steps,
250             static_candidates: Vec::new(),
251             unsatisfied_predicates: Vec::new(),
252         }
253     }
254
255     fn reset(&mut self) {
256         self.inherent_candidates.clear();
257         self.extension_candidates.clear();
258         self.impl_dups.clear();
259         self.static_candidates.clear();
260     }
261
262     fn tcx(&self) -> &'a ty::ctxt<'tcx> {
263         self.fcx.tcx()
264     }
265
266     fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
267         self.fcx.infcx()
268     }
269
270     ///////////////////////////////////////////////////////////////////////////
271     // CANDIDATE ASSEMBLY
272
273     fn assemble_inherent_candidates(&mut self) {
274         let steps = self.steps.clone();
275         for step in steps.iter() {
276             self.assemble_probe(step.self_ty);
277         }
278     }
279
280     fn assemble_probe(&mut self, self_ty: Ty<'tcx>) {
281         debug!("assemble_probe: self_ty={:?}",
282                self_ty);
283
284         match self_ty.sty {
285             ty::TyTrait(box ref data) => {
286                 self.assemble_inherent_candidates_from_object(self_ty, data);
287                 self.assemble_inherent_impl_candidates_for_type(data.principal_def_id());
288             }
289             ty::TyEnum(did, _) |
290             ty::TyStruct(did, _) |
291             ty::TyClosure(did, _) => {
292                 self.assemble_inherent_impl_candidates_for_type(did);
293             }
294             ty::TyBox(_) => {
295                 if let Some(box_did) = self.tcx().lang_items.owned_box() {
296                     self.assemble_inherent_impl_candidates_for_type(box_did);
297                 }
298             }
299             ty::TyParam(p) => {
300                 self.assemble_inherent_candidates_from_param(self_ty, p);
301             }
302             ty::TyChar => {
303                 let lang_def_id = self.tcx().lang_items.char_impl();
304                 self.assemble_inherent_impl_for_primitive(lang_def_id);
305             }
306             ty::TyStr => {
307                 let lang_def_id = self.tcx().lang_items.str_impl();
308                 self.assemble_inherent_impl_for_primitive(lang_def_id);
309             }
310             ty::TySlice(_) => {
311                 let lang_def_id = self.tcx().lang_items.slice_impl();
312                 self.assemble_inherent_impl_for_primitive(lang_def_id);
313             }
314             ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: ast::MutImmutable }) => {
315                 let lang_def_id = self.tcx().lang_items.const_ptr_impl();
316                 self.assemble_inherent_impl_for_primitive(lang_def_id);
317             }
318             ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: ast::MutMutable }) => {
319                 let lang_def_id = self.tcx().lang_items.mut_ptr_impl();
320                 self.assemble_inherent_impl_for_primitive(lang_def_id);
321             }
322             ty::TyInt(ast::TyI8) => {
323                 let lang_def_id = self.tcx().lang_items.i8_impl();
324                 self.assemble_inherent_impl_for_primitive(lang_def_id);
325             }
326             ty::TyInt(ast::TyI16) => {
327                 let lang_def_id = self.tcx().lang_items.i16_impl();
328                 self.assemble_inherent_impl_for_primitive(lang_def_id);
329             }
330             ty::TyInt(ast::TyI32) => {
331                 let lang_def_id = self.tcx().lang_items.i32_impl();
332                 self.assemble_inherent_impl_for_primitive(lang_def_id);
333             }
334             ty::TyInt(ast::TyI64) => {
335                 let lang_def_id = self.tcx().lang_items.i64_impl();
336                 self.assemble_inherent_impl_for_primitive(lang_def_id);
337             }
338             ty::TyInt(ast::TyIs) => {
339                 let lang_def_id = self.tcx().lang_items.isize_impl();
340                 self.assemble_inherent_impl_for_primitive(lang_def_id);
341             }
342             ty::TyUint(ast::TyU8) => {
343                 let lang_def_id = self.tcx().lang_items.u8_impl();
344                 self.assemble_inherent_impl_for_primitive(lang_def_id);
345             }
346             ty::TyUint(ast::TyU16) => {
347                 let lang_def_id = self.tcx().lang_items.u16_impl();
348                 self.assemble_inherent_impl_for_primitive(lang_def_id);
349             }
350             ty::TyUint(ast::TyU32) => {
351                 let lang_def_id = self.tcx().lang_items.u32_impl();
352                 self.assemble_inherent_impl_for_primitive(lang_def_id);
353             }
354             ty::TyUint(ast::TyU64) => {
355                 let lang_def_id = self.tcx().lang_items.u64_impl();
356                 self.assemble_inherent_impl_for_primitive(lang_def_id);
357             }
358             ty::TyUint(ast::TyUs) => {
359                 let lang_def_id = self.tcx().lang_items.usize_impl();
360                 self.assemble_inherent_impl_for_primitive(lang_def_id);
361             }
362             ty::TyFloat(ast::TyF32) => {
363                 let lang_def_id = self.tcx().lang_items.f32_impl();
364                 self.assemble_inherent_impl_for_primitive(lang_def_id);
365             }
366             ty::TyFloat(ast::TyF64) => {
367                 let lang_def_id = self.tcx().lang_items.f64_impl();
368                 self.assemble_inherent_impl_for_primitive(lang_def_id);
369             }
370             _ => {
371             }
372         }
373     }
374
375     fn assemble_inherent_impl_for_primitive(&mut self, lang_def_id: Option<ast::DefId>) {
376         if let Some(impl_def_id) = lang_def_id {
377             self.tcx().populate_implementations_for_primitive_if_necessary(impl_def_id);
378
379             self.assemble_inherent_impl_probe(impl_def_id);
380         }
381     }
382
383     fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) {
384         // Read the inherent implementation candidates for this type from the
385         // metadata if necessary.
386         self.tcx().populate_inherent_implementations_for_type_if_necessary(def_id);
387
388         if let Some(impl_infos) = self.tcx().inherent_impls.borrow().get(&def_id) {
389             for &impl_def_id in impl_infos.iter() {
390                 self.assemble_inherent_impl_probe(impl_def_id);
391             }
392         }
393     }
394
395     fn assemble_inherent_impl_probe(&mut self, impl_def_id: ast::DefId) {
396         if !self.impl_dups.insert(impl_def_id) {
397             return; // already visited
398         }
399
400         debug!("assemble_inherent_impl_probe {:?}", impl_def_id);
401
402         let item = match impl_item(self.tcx(), impl_def_id, self.item_name) {
403             Some(m) => m,
404             None => { return; } // No method with correct name on this impl
405         };
406
407         if !self.has_applicable_self(&item) {
408             // No receiver declared. Not a candidate.
409             return self.record_static_candidate(ImplSource(impl_def_id));
410         }
411
412         let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
413         let impl_ty = impl_ty.subst(self.tcx(), &impl_substs);
414
415         // Determine the receiver type that the method itself expects.
416         let xform_self_ty = self.xform_self_ty(&item, impl_ty, &impl_substs);
417
418         // We can't use normalize_associated_types_in as it will pollute the
419         // fcx's fulfillment context after this probe is over.
420         let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
421         let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx());
422         let traits::Normalized { value: xform_self_ty, obligations } =
423             traits::normalize(selcx, cause, &xform_self_ty);
424         debug!("assemble_inherent_impl_probe: xform_self_ty = {:?}",
425                xform_self_ty);
426
427         self.inherent_candidates.push(Candidate {
428             xform_self_ty: xform_self_ty,
429             item: item,
430             kind: InherentImplCandidate(impl_substs, obligations)
431         });
432     }
433
434     fn assemble_inherent_candidates_from_object(&mut self,
435                                                 self_ty: Ty<'tcx>,
436                                                 data: &ty::TraitTy<'tcx>) {
437         debug!("assemble_inherent_candidates_from_object(self_ty={:?})",
438                self_ty);
439
440         // It is illegal to invoke a method on a trait instance that
441         // refers to the `Self` type. An error will be reported by
442         // `enforce_object_limitations()` if the method refers to the
443         // `Self` type anywhere other than the receiver. Here, we use
444         // a substitution that replaces `Self` with the object type
445         // itself. Hence, a `&self` method will wind up with an
446         // argument type like `&Trait`.
447         let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(), self_ty);
448         self.elaborate_bounds(&[trait_ref], |this, new_trait_ref, item| {
449             let new_trait_ref = this.erase_late_bound_regions(&new_trait_ref);
450
451             let xform_self_ty = this.xform_self_ty(&item,
452                                                    new_trait_ref.self_ty(),
453                                                    new_trait_ref.substs);
454
455             this.inherent_candidates.push(Candidate {
456                 xform_self_ty: xform_self_ty,
457                 item: item,
458                 kind: ObjectCandidate
459             });
460         });
461     }
462
463     fn assemble_inherent_candidates_from_param(&mut self,
464                                                _rcvr_ty: Ty<'tcx>,
465                                                param_ty: ty::ParamTy) {
466         // FIXME -- Do we want to commit to this behavior for param bounds?
467
468         let bounds: Vec<_> =
469             self.fcx.inh.infcx.parameter_environment.caller_bounds
470             .iter()
471             .filter_map(|predicate| {
472                 match *predicate {
473                     ty::Predicate::Trait(ref trait_predicate) => {
474                         match trait_predicate.0.trait_ref.self_ty().sty {
475                             ty::TyParam(ref p) if *p == param_ty => {
476                                 Some(trait_predicate.to_poly_trait_ref())
477                             }
478                             _ => None
479                         }
480                     }
481                     ty::Predicate::Equate(..) |
482                     ty::Predicate::Projection(..) |
483                     ty::Predicate::RegionOutlives(..) |
484                     ty::Predicate::TypeOutlives(..) => {
485                         None
486                     }
487                 }
488             })
489             .collect();
490
491         self.elaborate_bounds(&bounds, |this, poly_trait_ref, item| {
492             let trait_ref =
493                 this.erase_late_bound_regions(&poly_trait_ref);
494
495             let xform_self_ty =
496                 this.xform_self_ty(&item,
497                                    trait_ref.self_ty(),
498                                    trait_ref.substs);
499
500             if let Some(ref m) = item.as_opt_method() {
501                 debug!("found match: trait_ref={:?} substs={:?} m={:?}",
502                        trait_ref,
503                        trait_ref.substs,
504                        m);
505                 assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
506                            trait_ref.substs.types.get_slice(subst::TypeSpace).len());
507                 assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
508                            trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
509                 assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
510                            trait_ref.substs.types.get_slice(subst::SelfSpace).len());
511                 assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
512                            trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
513             }
514
515             // Because this trait derives from a where-clause, it
516             // should not contain any inference variables or other
517             // artifacts. This means it is safe to put into the
518             // `WhereClauseCandidate` and (eventually) into the
519             // `WhereClausePick`.
520             assert!(!trait_ref.substs.types.needs_infer());
521
522             this.inherent_candidates.push(Candidate {
523                 xform_self_ty: xform_self_ty,
524                 item: item,
525                 kind: WhereClauseCandidate(poly_trait_ref)
526             });
527         });
528     }
529
530     // Do a search through a list of bounds, using a callback to actually
531     // create the candidates.
532     fn elaborate_bounds<F>(
533         &mut self,
534         bounds: &[ty::PolyTraitRef<'tcx>],
535         mut mk_cand: F,
536     ) where
537         F: for<'b> FnMut(
538             &mut ProbeContext<'b, 'tcx>,
539             ty::PolyTraitRef<'tcx>,
540             ty::ImplOrTraitItem<'tcx>,
541         ),
542     {
543         debug!("elaborate_bounds(bounds={:?})", bounds);
544
545         let tcx = self.tcx();
546         for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
547             let item = match trait_item(tcx,
548                                         bound_trait_ref.def_id(),
549                                         self.item_name) {
550                 Some(v) => v,
551                 None => { continue; }
552             };
553
554             if !self.has_applicable_self(&item) {
555                 self.record_static_candidate(TraitSource(bound_trait_ref.def_id()));
556             } else {
557                 mk_cand(self, bound_trait_ref, item);
558             }
559         }
560     }
561
562     fn assemble_extension_candidates_for_traits_in_scope(&mut self,
563                                                          expr_id: ast::NodeId)
564                                                          -> Result<(), MethodError<'tcx>>
565     {
566         let mut duplicates = HashSet::new();
567         let opt_applicable_traits = self.fcx.ccx.trait_map.get(&expr_id);
568         if let Some(applicable_traits) = opt_applicable_traits {
569             for &trait_did in applicable_traits {
570                 if duplicates.insert(trait_did) {
571                     try!(self.assemble_extension_candidates_for_trait(trait_did));
572                 }
573             }
574         }
575         Ok(())
576     }
577
578     fn assemble_extension_candidates_for_all_traits(&mut self) -> Result<(), MethodError<'tcx>> {
579         let mut duplicates = HashSet::new();
580         for trait_info in suggest::all_traits(self.fcx.ccx) {
581             if duplicates.insert(trait_info.def_id) {
582                 try!(self.assemble_extension_candidates_for_trait(trait_info.def_id));
583             }
584         }
585         Ok(())
586     }
587
588     fn assemble_extension_candidates_for_trait(&mut self,
589                                                trait_def_id: ast::DefId)
590                                                -> Result<(), MethodError<'tcx>>
591     {
592         debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})",
593                trait_def_id);
594
595         // Check whether `trait_def_id` defines a method with suitable name:
596         let trait_items =
597             self.tcx().trait_items(trait_def_id);
598         let maybe_item =
599             trait_items.iter()
600                        .find(|item| item.name() == self.item_name);
601         let item = match maybe_item {
602             Some(i) => i,
603             None => { return Ok(()); }
604         };
605
606         // Check whether `trait_def_id` defines a method with suitable name:
607         if !self.has_applicable_self(item) {
608             debug!("method has inapplicable self");
609             self.record_static_candidate(TraitSource(trait_def_id));
610             return Ok(());
611         }
612
613         self.assemble_extension_candidates_for_trait_impls(trait_def_id, item.clone());
614
615         try!(self.assemble_closure_candidates(trait_def_id, item.clone()));
616
617         self.assemble_projection_candidates(trait_def_id, item.clone());
618
619         self.assemble_where_clause_candidates(trait_def_id, item.clone());
620
621         Ok(())
622     }
623
624     fn assemble_extension_candidates_for_trait_impls(&mut self,
625                                                      trait_def_id: ast::DefId,
626                                                      item: ty::ImplOrTraitItem<'tcx>)
627     {
628         let trait_def = self.tcx().lookup_trait_def(trait_def_id);
629
630         // FIXME(arielb1): can we use for_each_relevant_impl here?
631         trait_def.for_each_impl(self.tcx(), |impl_def_id| {
632             debug!("assemble_extension_candidates_for_trait_impl: trait_def_id={:?} \
633                                                                   impl_def_id={:?}",
634                    trait_def_id,
635                    impl_def_id);
636
637             if !self.impl_can_possibly_match(impl_def_id) {
638                 return;
639             }
640
641             let (_, impl_substs) = self.impl_ty_and_substs(impl_def_id);
642
643             debug!("impl_substs={:?}", impl_substs);
644
645             let impl_trait_ref =
646                 self.tcx().impl_trait_ref(impl_def_id)
647                 .unwrap() // we know this is a trait impl
648                 .subst(self.tcx(), &impl_substs);
649
650             debug!("impl_trait_ref={:?}", impl_trait_ref);
651
652             // Determine the receiver type that the method itself expects.
653             let xform_self_ty =
654                 self.xform_self_ty(&item,
655                                    impl_trait_ref.self_ty(),
656                                    impl_trait_ref.substs);
657
658             // Normalize the receiver. We can't use normalize_associated_types_in
659             // as it will pollute the fcx's fulfillment context after this probe
660             // is over.
661             let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
662             let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx());
663             let traits::Normalized { value: xform_self_ty, obligations } =
664                 traits::normalize(selcx, cause, &xform_self_ty);
665
666             debug!("xform_self_ty={:?}", xform_self_ty);
667
668             self.extension_candidates.push(Candidate {
669                 xform_self_ty: xform_self_ty,
670                 item: item.clone(),
671                 kind: ExtensionImplCandidate(impl_def_id, impl_substs, obligations)
672             });
673         });
674     }
675
676     fn impl_can_possibly_match(&self, impl_def_id: ast::DefId) -> bool {
677         let simplified_steps = match self.opt_simplified_steps {
678             Some(ref simplified_steps) => simplified_steps,
679             None => { return true; }
680         };
681
682         let impl_type = self.tcx().lookup_item_type(impl_def_id);
683         let impl_simplified_type =
684             match fast_reject::simplify_type(self.tcx(), impl_type.ty, false) {
685                 Some(simplified_type) => simplified_type,
686                 None => { return true; }
687             };
688
689         simplified_steps.contains(&impl_simplified_type)
690     }
691
692     fn assemble_closure_candidates(&mut self,
693                                    trait_def_id: ast::DefId,
694                                    item: ty::ImplOrTraitItem<'tcx>)
695                                    -> Result<(), MethodError<'tcx>>
696     {
697         // Check if this is one of the Fn,FnMut,FnOnce traits.
698         let tcx = self.tcx();
699         let kind = if Some(trait_def_id) == tcx.lang_items.fn_trait() {
700             ty::FnClosureKind
701         } else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
702             ty::FnMutClosureKind
703         } else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
704             ty::FnOnceClosureKind
705         } else {
706             return Ok(());
707         };
708
709         // Check if there is an unboxed-closure self-type in the list of receivers.
710         // If so, add "synthetic impls".
711         let steps = self.steps.clone();
712         for step in steps.iter() {
713             let closure_def_id = match step.self_ty.sty {
714                 ty::TyClosure(a, _) => a,
715                 _ => continue,
716             };
717
718             let closure_kinds = &self.fcx.inh.tables.borrow().closure_kinds;
719             let closure_kind = match closure_kinds.get(&closure_def_id) {
720                 Some(&k) => k,
721                 None => {
722                     return Err(MethodError::ClosureAmbiguity(trait_def_id));
723                 }
724             };
725
726             // this closure doesn't implement the right kind of `Fn` trait
727             if !closure_kind.extends(kind) {
728                 continue;
729             }
730
731             // create some substitutions for the argument/return type;
732             // for the purposes of our method lookup, we only take
733             // receiver type into account, so we can just substitute
734             // fresh types here to use during substitution and subtyping.
735             let trait_def = self.tcx().lookup_trait_def(trait_def_id);
736             let substs = self.infcx().fresh_substs_for_trait(self.span,
737                                                              &trait_def.generics,
738                                                              step.self_ty);
739
740             let xform_self_ty = self.xform_self_ty(&item,
741                                                    step.self_ty,
742                                                    &substs);
743             self.inherent_candidates.push(Candidate {
744                 xform_self_ty: xform_self_ty,
745                 item: item.clone(),
746                 kind: TraitCandidate
747             });
748         }
749
750         Ok(())
751     }
752
753     fn assemble_projection_candidates(&mut self,
754                                       trait_def_id: ast::DefId,
755                                       item: ty::ImplOrTraitItem<'tcx>)
756     {
757         debug!("assemble_projection_candidates(\
758                trait_def_id={:?}, \
759                item={:?})",
760                trait_def_id,
761                item);
762
763         for step in self.steps.iter() {
764             debug!("assemble_projection_candidates: step={:?}",
765                    step);
766
767             let projection_trait_ref = match step.self_ty.sty {
768                 ty::TyProjection(ref data) => &data.trait_ref,
769                 _ => continue,
770             };
771
772             debug!("assemble_projection_candidates: projection_trait_ref={:?}",
773                    projection_trait_ref);
774
775             let trait_predicates = self.tcx().lookup_predicates(projection_trait_ref.def_id);
776             let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
777             let predicates = bounds.predicates.into_vec();
778             debug!("assemble_projection_candidates: predicates={:?}",
779                    predicates);
780             for poly_bound in
781                 traits::elaborate_predicates(self.tcx(), predicates)
782                 .filter_map(|p| p.to_opt_poly_trait_ref())
783                 .filter(|b| b.def_id() == trait_def_id)
784             {
785                 let bound = self.erase_late_bound_regions(&poly_bound);
786
787                 debug!("assemble_projection_candidates: projection_trait_ref={:?} bound={:?}",
788                        projection_trait_ref,
789                        bound);
790
791                 if self.infcx().can_equate(&step.self_ty, &bound.self_ty()).is_ok() {
792                     let xform_self_ty = self.xform_self_ty(&item,
793                                                            bound.self_ty(),
794                                                            bound.substs);
795
796                     debug!("assemble_projection_candidates: bound={:?} xform_self_ty={:?}",
797                            bound,
798                            xform_self_ty);
799
800                     self.extension_candidates.push(Candidate {
801                         xform_self_ty: xform_self_ty,
802                         item: item.clone(),
803                         kind: TraitCandidate
804                     });
805                 }
806             }
807         }
808     }
809
810     fn assemble_where_clause_candidates(&mut self,
811                                         trait_def_id: ast::DefId,
812                                         item: ty::ImplOrTraitItem<'tcx>)
813     {
814         debug!("assemble_where_clause_candidates(trait_def_id={:?})",
815                trait_def_id);
816
817         let caller_predicates = self.fcx.inh.infcx.parameter_environment.caller_bounds.clone();
818         for poly_bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
819                           .filter_map(|p| p.to_opt_poly_trait_ref())
820                           .filter(|b| b.def_id() == trait_def_id)
821         {
822             let bound = self.erase_late_bound_regions(&poly_bound);
823             let xform_self_ty = self.xform_self_ty(&item,
824                                                    bound.self_ty(),
825                                                    bound.substs);
826
827             debug!("assemble_where_clause_candidates: bound={:?} xform_self_ty={:?}",
828                    bound,
829                    xform_self_ty);
830
831             self.extension_candidates.push(Candidate {
832                 xform_self_ty: xform_self_ty,
833                 item: item.clone(),
834                 kind: WhereClauseCandidate(poly_bound)
835             });
836         }
837     }
838
839     ///////////////////////////////////////////////////////////////////////////
840     // THE ACTUAL SEARCH
841
842     fn pick(mut self) -> PickResult<'tcx> {
843         match self.pick_core() {
844             Some(r) => return r,
845             None => {}
846         }
847
848         let static_candidates = mem::replace(&mut self.static_candidates, vec![]);
849         let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]);
850
851         // things failed, so lets look at all traits, for diagnostic purposes now:
852         self.reset();
853
854         let span = self.span;
855         let tcx = self.tcx();
856
857         try!(self.assemble_extension_candidates_for_all_traits());
858
859         let out_of_scope_traits = match self.pick_core() {
860             Some(Ok(p)) => vec![p.item.container().id()],
861             Some(Err(MethodError::Ambiguity(v))) => v.into_iter().map(|source| {
862                 match source {
863                     TraitSource(id) => id,
864                     ImplSource(impl_id) => {
865                         match tcx.trait_id_of_impl(impl_id) {
866                             Some(id) => id,
867                             None =>
868                                 tcx.sess.span_bug(span,
869                                                   "found inherent method when looking at traits")
870                         }
871                     }
872                 }
873             }).collect(),
874             Some(Err(MethodError::NoMatch(NoMatchData { out_of_scope_traits: others, .. }))) => {
875                 assert!(others.is_empty());
876                 vec![]
877             }
878             Some(Err(MethodError::ClosureAmbiguity(..))) => {
879                 // this error only occurs when assembling candidates
880                 tcx.sess.span_bug(span, "encountered ClosureAmbiguity from pick_core");
881             }
882             None => vec![],
883         };
884
885         Err(MethodError::NoMatch(NoMatchData::new(static_candidates, unsatisfied_predicates,
886                                                   out_of_scope_traits, self.mode)))
887     }
888
889     fn pick_core(&mut self) -> Option<PickResult<'tcx>> {
890         let steps = self.steps.clone();
891
892         // find the first step that works
893         steps.iter().filter_map(|step| self.pick_step(step)).next()
894     }
895
896     fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option<PickResult<'tcx>> {
897         debug!("pick_step: step={:?}", step);
898
899         if step.self_ty.references_error() {
900             return None;
901         }
902
903         match self.pick_by_value_method(step) {
904             Some(result) => return Some(result),
905             None => {}
906         }
907
908         self.pick_autorefd_method(step)
909     }
910
911     fn pick_by_value_method(&mut self,
912                             step: &CandidateStep<'tcx>)
913                             -> Option<PickResult<'tcx>>
914     {
915         /*!
916          * For each type `T` in the step list, this attempts to find a
917          * method where the (transformed) self type is exactly `T`. We
918          * do however do one transformation on the adjustment: if we
919          * are passing a region pointer in, we will potentially
920          * *reborrow* it to a shorter lifetime. This allows us to
921          * transparently pass `&mut` pointers, in particular, without
922          * consuming them for their entire lifetime.
923          */
924
925         if step.unsize {
926             return None;
927         }
928
929         self.pick_method(step.self_ty).map(|r| r.map(|mut pick| {
930             pick.autoderefs = step.autoderefs;
931
932             // Insert a `&*` or `&mut *` if this is a reference type:
933             if let ty::TyRef(_, mt) = step.self_ty.sty {
934                 pick.autoderefs += 1;
935                 pick.autoref = Some(mt.mutbl);
936             }
937
938             pick
939         }))
940     }
941
942     fn pick_autorefd_method(&mut self,
943                             step: &CandidateStep<'tcx>)
944                             -> Option<PickResult<'tcx>>
945     {
946         let tcx = self.tcx();
947
948         // In general, during probing we erase regions. See
949         // `impl_self_ty()` for an explanation.
950         let region = tcx.mk_region(ty::ReStatic);
951
952         // Search through mutabilities in order to find one where pick works:
953         [ast::MutImmutable, ast::MutMutable].iter().filter_map(|&m| {
954             let autoref_ty = tcx.mk_ref(region, ty::TypeAndMut {
955                 ty: step.self_ty,
956                 mutbl: m
957             });
958             self.pick_method(autoref_ty).map(|r| r.map(|mut pick| {
959                 pick.autoderefs = step.autoderefs;
960                 pick.autoref = Some(m);
961                 pick.unsize = if step.unsize {
962                     Some(step.self_ty)
963                 } else {
964                     None
965                 };
966                 pick
967             }))
968         }).nth(0)
969     }
970
971     fn pick_method(&mut self, self_ty: Ty<'tcx>) -> Option<PickResult<'tcx>> {
972         debug!("pick_method(self_ty={})", self.infcx().ty_to_string(self_ty));
973
974         let mut possibly_unsatisfied_predicates = Vec::new();
975
976         debug!("searching inherent candidates");
977         match self.consider_candidates(self_ty, &self.inherent_candidates,
978                                        &mut possibly_unsatisfied_predicates) {
979             None => {}
980             Some(pick) => {
981                 return Some(pick);
982             }
983         }
984
985         debug!("searching extension candidates");
986         let res = self.consider_candidates(self_ty, &self.extension_candidates,
987                                            &mut possibly_unsatisfied_predicates);
988         if let None = res {
989             self.unsatisfied_predicates.extend(possibly_unsatisfied_predicates);
990         }
991         res
992     }
993
994     fn consider_candidates(&self,
995                            self_ty: Ty<'tcx>,
996                            probes: &[Candidate<'tcx>],
997                            possibly_unsatisfied_predicates: &mut Vec<TraitRef<'tcx>>)
998                            -> Option<PickResult<'tcx>> {
999         let mut applicable_candidates: Vec<_> =
1000             probes.iter()
1001                   .filter(|&probe| self.consider_probe(self_ty,
1002                                                        probe,possibly_unsatisfied_predicates))
1003                   .collect();
1004
1005         debug!("applicable_candidates: {:?}", applicable_candidates);
1006
1007         if applicable_candidates.len() > 1 {
1008             match self.collapse_candidates_to_trait_pick(&applicable_candidates[..]) {
1009                 Some(pick) => { return Some(Ok(pick)); }
1010                 None => { }
1011             }
1012         }
1013
1014         if applicable_candidates.len() > 1 {
1015             let sources = probes.iter().map(|p| p.to_source()).collect();
1016             return Some(Err(MethodError::Ambiguity(sources)));
1017         }
1018
1019         applicable_candidates.pop().map(|probe| {
1020             Ok(probe.to_unadjusted_pick())
1021         })
1022     }
1023
1024     fn consider_probe(&self, self_ty: Ty<'tcx>, probe: &Candidate<'tcx>,
1025                       possibly_unsatisfied_predicates: &mut Vec<TraitRef<'tcx>>) -> bool {
1026         debug!("consider_probe: self_ty={:?} probe={:?}",
1027                self_ty,
1028                probe);
1029
1030         self.infcx().probe(|_| {
1031             // First check that the self type can be related.
1032             match self.make_sub_ty(self_ty, probe.xform_self_ty) {
1033                 Ok(()) => { }
1034                 Err(_) => {
1035                     debug!("--> cannot relate self-types");
1036                     return false;
1037                 }
1038             }
1039
1040             // If so, impls may carry other conditions (e.g., where
1041             // clauses) that must be considered. Make sure that those
1042             // match as well (or at least may match, sometimes we
1043             // don't have enough information to fully evaluate).
1044             let (impl_def_id, substs, ref_obligations) = match probe.kind {
1045                 InherentImplCandidate(ref substs, ref ref_obligations) => {
1046                     (probe.item.container().id(), substs, ref_obligations)
1047                 }
1048
1049                 ExtensionImplCandidate(impl_def_id, ref substs, ref ref_obligations) => {
1050                     (impl_def_id, substs, ref_obligations)
1051                 }
1052
1053                 ObjectCandidate(..) |
1054                 TraitCandidate |
1055                 WhereClauseCandidate(..) => {
1056                     // These have no additional conditions to check.
1057                     return true;
1058                 }
1059             };
1060
1061             let selcx = &mut traits::SelectionContext::new(self.infcx());
1062             let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
1063
1064             // Check whether the impl imposes obligations we have to worry about.
1065             let impl_bounds = self.tcx().lookup_predicates(impl_def_id);
1066             let impl_bounds = impl_bounds.instantiate(self.tcx(), substs);
1067             let traits::Normalized { value: impl_bounds,
1068                                         obligations: norm_obligations } =
1069                 traits::normalize(selcx, cause.clone(), &impl_bounds);
1070
1071             // Convert the bounds into obligations.
1072             let obligations =
1073                 traits::predicates_for_generics(cause.clone(),
1074                                                 &impl_bounds);
1075             debug!("impl_obligations={:?}", obligations);
1076
1077             // Evaluate those obligations to see if they might possibly hold.
1078             let mut all_true = true;
1079             for o in obligations.iter()
1080                 .chain(norm_obligations.iter())
1081                 .chain(ref_obligations.iter()) {
1082                 if !selcx.evaluate_obligation(o) {
1083                     all_true = false;
1084                     if let &ty::Predicate::Trait(ref pred) = &o.predicate {
1085                         possibly_unsatisfied_predicates.push(pred.0.trait_ref);
1086                     }
1087                 }
1088             }
1089             all_true
1090         })
1091     }
1092
1093     /// Sometimes we get in a situation where we have multiple probes that are all impls of the
1094     /// same trait, but we don't know which impl to use. In this case, since in all cases the
1095     /// external interface of the method can be determined from the trait, it's ok not to decide.
1096     /// We can basically just collapse all of the probes for various impls into one where-clause
1097     /// probe. This will result in a pending obligation so when more type-info is available we can
1098     /// make the final decision.
1099     ///
1100     /// Example (`src/test/run-pass/method-two-trait-defer-resolution-1.rs`):
1101     ///
1102     /// ```
1103     /// trait Foo { ... }
1104     /// impl Foo for Vec<int> { ... }
1105     /// impl Foo for Vec<usize> { ... }
1106     /// ```
1107     ///
1108     /// Now imagine the receiver is `Vec<_>`. It doesn't really matter at this time which impl we
1109     /// use, so it's ok to just commit to "using the method from the trait Foo".
1110     fn collapse_candidates_to_trait_pick(&self,
1111                                          probes: &[&Candidate<'tcx>])
1112                                          -> Option<Pick<'tcx>> {
1113         // Do all probes correspond to the same trait?
1114         let container = probes[0].item.container();
1115         match container {
1116             ty::TraitContainer(_) => {}
1117             ty::ImplContainer(_) => return None
1118         }
1119         if probes[1..].iter().any(|p| p.item.container() != container) {
1120             return None;
1121         }
1122
1123         // If so, just use this trait and call it a day.
1124         Some(Pick {
1125             item: probes[0].item.clone(),
1126             kind: TraitPick,
1127             autoderefs: 0,
1128             autoref: None,
1129             unsize: None
1130         })
1131     }
1132
1133     ///////////////////////////////////////////////////////////////////////////
1134     // MISCELLANY
1135
1136     fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::UnitResult<'tcx> {
1137         self.infcx().sub_types(false, infer::Misc(DUMMY_SP), sub, sup)
1138     }
1139
1140     fn has_applicable_self(&self, item: &ty::ImplOrTraitItem) -> bool {
1141         // "fast track" -- check for usage of sugar
1142         match *item {
1143             ty::ImplOrTraitItem::MethodTraitItem(ref method) =>
1144                 match method.explicit_self {
1145                     ty::StaticExplicitSelfCategory => self.mode == Mode::Path,
1146                     ty::ByValueExplicitSelfCategory |
1147                     ty::ByReferenceExplicitSelfCategory(..) |
1148                     ty::ByBoxExplicitSelfCategory => true,
1149                 },
1150             ty::ImplOrTraitItem::ConstTraitItem(..) => self.mode == Mode::Path,
1151             _ => false,
1152         }
1153         // FIXME -- check for types that deref to `Self`,
1154         // like `Rc<Self>` and so on.
1155         //
1156         // Note also that the current code will break if this type
1157         // includes any of the type parameters defined on the method
1158         // -- but this could be overcome.
1159     }
1160
1161     fn record_static_candidate(&mut self, source: CandidateSource) {
1162         self.static_candidates.push(source);
1163     }
1164
1165     fn xform_self_ty(&self,
1166                      item: &ty::ImplOrTraitItem<'tcx>,
1167                      impl_ty: Ty<'tcx>,
1168                      substs: &subst::Substs<'tcx>)
1169                      -> Ty<'tcx>
1170     {
1171         match item.as_opt_method() {
1172             Some(ref method) => self.xform_method_self_ty(method, impl_ty,
1173                                                           substs),
1174             None => impl_ty,
1175         }
1176     }
1177
1178     fn xform_method_self_ty(&self,
1179                             method: &Rc<ty::Method<'tcx>>,
1180                             impl_ty: Ty<'tcx>,
1181                             substs: &subst::Substs<'tcx>)
1182                             -> Ty<'tcx>
1183     {
1184         debug!("xform_self_ty(impl_ty={:?}, self_ty={:?}, substs={:?})",
1185                impl_ty,
1186                method.fty.sig.0.inputs.get(0),
1187                substs);
1188
1189         assert!(!substs.has_escaping_regions());
1190
1191         // It is possible for type parameters or early-bound lifetimes
1192         // to appear in the signature of `self`. The substitutions we
1193         // are given do not include type/lifetime parameters for the
1194         // method yet. So create fresh variables here for those too,
1195         // if there are any.
1196         assert_eq!(substs.types.len(subst::FnSpace), 0);
1197         assert_eq!(substs.regions().len(subst::FnSpace), 0);
1198
1199         if self.mode == Mode::Path {
1200             return impl_ty;
1201         }
1202
1203         let placeholder;
1204         let mut substs = substs;
1205         if
1206             !method.generics.types.is_empty_in(subst::FnSpace) ||
1207             !method.generics.regions.is_empty_in(subst::FnSpace)
1208         {
1209             let method_types =
1210                 self.infcx().type_vars_for_defs(
1211                     method.generics.types.get_slice(subst::FnSpace));
1212
1213             // In general, during probe we erase regions. See
1214             // `impl_self_ty()` for an explanation.
1215             let method_regions =
1216                 method.generics.regions.get_slice(subst::FnSpace)
1217                 .iter()
1218                 .map(|_| ty::ReStatic)
1219                 .collect();
1220
1221             placeholder = (*substs).clone().with_method(method_types, method_regions);
1222             substs = &placeholder;
1223         }
1224
1225         // Erase any late-bound regions from the method and substitute
1226         // in the values from the substitution.
1227         let xform_self_ty = method.fty.sig.input(0);
1228         let xform_self_ty = self.erase_late_bound_regions(&xform_self_ty);
1229         let xform_self_ty = xform_self_ty.subst(self.tcx(), substs);
1230
1231         xform_self_ty
1232     }
1233
1234     /// Get the type of an impl and generate substitutions with placeholders.
1235     fn impl_ty_and_substs(&self,
1236                           impl_def_id: ast::DefId)
1237                           -> (Ty<'tcx>, subst::Substs<'tcx>)
1238     {
1239         let impl_pty = self.tcx().lookup_item_type(impl_def_id);
1240
1241         let type_vars =
1242             impl_pty.generics.types.map(
1243                 |_| self.infcx().next_ty_var());
1244
1245         let region_placeholders =
1246             impl_pty.generics.regions.map(
1247                 |_| ty::ReStatic); // see erase_late_bound_regions() for an expl of why 'static
1248
1249         let substs = subst::Substs::new(type_vars, region_placeholders);
1250         (impl_pty.ty, substs)
1251     }
1252
1253     /// Replace late-bound-regions bound by `value` with `'static` using
1254     /// `ty::erase_late_bound_regions`.
1255     ///
1256     /// This is only a reasonable thing to do during the *probe* phase, not the *confirm* phase, of
1257     /// method matching. It is reasonable during the probe phase because we don't consider region
1258     /// relationships at all. Therefore, we can just replace all the region variables with 'static
1259     /// rather than creating fresh region variables. This is nice for two reasons:
1260     ///
1261     /// 1. Because the numbers of the region variables would otherwise be fairly unique to this
1262     ///    particular method call, it winds up creating fewer types overall, which helps for memory
1263     ///    usage. (Admittedly, this is a rather small effect, though measureable.)
1264     ///
1265     /// 2. It makes it easier to deal with higher-ranked trait bounds, because we can replace any
1266     ///    late-bound regions with 'static. Otherwise, if we were going to replace late-bound
1267     ///    regions with actual region variables as is proper, we'd have to ensure that the same
1268     ///    region got replaced with the same variable, which requires a bit more coordination
1269     ///    and/or tracking the substitution and
1270     ///    so forth.
1271     fn erase_late_bound_regions<T>(&self, value: &ty::Binder<T>) -> T
1272         where T : TypeFoldable<'tcx>
1273     {
1274         self.tcx().erase_late_bound_regions(value)
1275     }
1276 }
1277
1278 fn impl_item<'tcx>(tcx: &ty::ctxt<'tcx>,
1279                    impl_def_id: ast::DefId,
1280                    item_name: ast::Name)
1281                    -> Option<ty::ImplOrTraitItem<'tcx>>
1282 {
1283     let impl_items = tcx.impl_items.borrow();
1284     let impl_items = impl_items.get(&impl_def_id).unwrap();
1285     impl_items
1286         .iter()
1287         .map(|&did| tcx.impl_or_trait_item(did.def_id()))
1288         .find(|item| item.name() == item_name)
1289 }
1290
1291 /// Find item with name `item_name` defined in `trait_def_id`
1292 /// and return it, or `None`, if no such item.
1293 fn trait_item<'tcx>(tcx: &ty::ctxt<'tcx>,
1294                     trait_def_id: ast::DefId,
1295                     item_name: ast::Name)
1296                     -> Option<ty::ImplOrTraitItem<'tcx>>
1297 {
1298     let trait_items = tcx.trait_items(trait_def_id);
1299     debug!("trait_method; items: {:?}", trait_items);
1300     trait_items.iter()
1301                .find(|item| item.name() == item_name)
1302                .cloned()
1303 }
1304
1305 impl<'tcx> Candidate<'tcx> {
1306     fn to_unadjusted_pick(&self) -> Pick<'tcx> {
1307         Pick {
1308             item: self.item.clone(),
1309             kind: match self.kind {
1310                 InherentImplCandidate(_, _) => InherentImplPick,
1311                 ExtensionImplCandidate(def_id, _, _) => {
1312                     ExtensionImplPick(def_id)
1313                 }
1314                 ObjectCandidate => ObjectPick,
1315                 TraitCandidate => TraitPick,
1316                 WhereClauseCandidate(ref trait_ref) => {
1317                     // Only trait derived from where-clauses should
1318                     // appear here, so they should not contain any
1319                     // inference variables or other artifacts. This
1320                     // means they are safe to put into the
1321                     // `WhereClausePick`.
1322                     assert!(!trait_ref.substs().types.needs_infer());
1323
1324                     WhereClausePick(trait_ref.clone())
1325                 }
1326             },
1327             autoderefs: 0,
1328             autoref: None,
1329             unsize: None
1330         }
1331     }
1332
1333     fn to_source(&self) -> CandidateSource {
1334         match self.kind {
1335             InherentImplCandidate(_, _) => {
1336                 ImplSource(self.item.container().id())
1337             }
1338             ExtensionImplCandidate(def_id, _, _) => ImplSource(def_id),
1339             ObjectCandidate |
1340             TraitCandidate |
1341             WhereClauseCandidate(_) => TraitSource(self.item.container().id()),
1342         }
1343     }
1344 }