]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/typeck/check/method/probe.rs
/*! -> //!
[rust.git] / src / librustc / middle / 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,Ambiguity,NoMatch};
12 use super::MethodIndex;
13 use super::{CandidateSource,ImplSource,TraitSource};
14
15 use middle::fast_reject;
16 use middle::subst;
17 use middle::subst::Subst;
18 use middle::traits;
19 use middle::ty::{mod, Ty};
20 use middle::ty_fold::HigherRankedFoldable;
21 use middle::typeck::check;
22 use middle::typeck::check::{FnCtxt, NoPreference};
23 use middle::typeck::{MethodObject};
24 use middle::typeck::infer;
25 use middle::typeck::infer::InferCtxt;
26 use syntax::ast;
27 use syntax::codemap::{Span, DUMMY_SP};
28 use std::collections::HashSet;
29 use std::rc::Rc;
30 use util::ppaux::Repr;
31
32 use self::CandidateKind::*;
33 pub use self::PickAdjustment::*;
34 pub use self::PickKind::*;
35
36 struct ProbeContext<'a, 'tcx:'a> {
37     fcx: &'a FnCtxt<'a, 'tcx>,
38     span: Span,
39     method_name: ast::Name,
40     steps: Rc<Vec<CandidateStep<'tcx>>>,
41     opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>,
42     inherent_candidates: Vec<Candidate<'tcx>>,
43     extension_candidates: Vec<Candidate<'tcx>>,
44     impl_dups: HashSet<ast::DefId>,
45     static_candidates: Vec<CandidateSource>,
46 }
47
48 struct CandidateStep<'tcx> {
49     self_ty: Ty<'tcx>,
50     adjustment: PickAdjustment,
51 }
52
53 struct Candidate<'tcx> {
54     xform_self_ty: Ty<'tcx>,
55     method_ty: Rc<ty::Method<'tcx>>,
56     kind: CandidateKind<'tcx>,
57 }
58
59 enum CandidateKind<'tcx> {
60     InherentImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>),
61     ObjectCandidate(MethodObject<'tcx>),
62     ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>,
63                            subst::Substs<'tcx>, MethodIndex),
64     UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
65     WhereClauseCandidate(Rc<ty::TraitRef<'tcx>>, MethodIndex),
66 }
67
68 pub struct Pick<'tcx> {
69     pub method_ty: Rc<ty::Method<'tcx>>,
70     pub adjustment: PickAdjustment,
71     pub kind: PickKind<'tcx>,
72 }
73
74 #[deriving(Clone,Show)]
75 pub enum PickKind<'tcx> {
76     InherentImplPick(/* Impl */ ast::DefId),
77     ObjectPick(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint),
78     ExtensionImplPick(/* Impl */ ast::DefId, MethodIndex),
79     TraitPick(/* Trait */ ast::DefId, MethodIndex),
80     WhereClausePick(/* Trait */ Rc<ty::TraitRef<'tcx>>, MethodIndex),
81 }
82
83 pub type PickResult<'tcx> = Result<Pick<'tcx>, MethodError>;
84
85 // This is a kind of "abstracted" version of ty::AutoAdjustment.  The
86 // difference is that it doesn't embed any regions or other
87 // specifics. The "confirmation" step recreates those details as
88 // needed.
89 #[deriving(Clone,Show)]
90 pub enum PickAdjustment {
91     // Indicates that the source expression should be autoderef'd N times
92     //
93     // A = expr | *expr | **expr
94     AutoDeref(uint),
95
96     // Indicates that the source expression should be autoderef'd N
97     // times and then "unsized". This should probably eventually go
98     // away in favor of just coercing method receivers.
99     //
100     // A = unsize(expr | *expr | **expr)
101     AutoUnsizeLength(/* number of autoderefs */ uint, /* length*/ uint),
102
103     // Indicates that an autoref is applied after some number of other adjustments
104     //
105     // A = &A | &mut A
106     AutoRef(ast::Mutability, Box<PickAdjustment>),
107 }
108
109 pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
110                        span: Span,
111                        method_name: ast::Name,
112                        self_ty: Ty<'tcx>,
113                        call_expr_id: ast::NodeId)
114                        -> PickResult<'tcx>
115 {
116     debug!("probe(self_ty={}, method_name={}, call_expr_id={})",
117            self_ty.repr(fcx.tcx()),
118            method_name,
119            call_expr_id);
120
121     // FIXME(#18741) -- right now, creating the steps involves evaluating the
122     // `*` operator, which registers obligations that then escape into
123     // the global fulfillment context and thus has global
124     // side-effects. This is a bit of a pain to refactor. So just let
125     // it ride, although it's really not great, and in fact could I
126     // think cause spurious errors. Really though this part should
127     // take place in the `fcx.infcx().probe` below.
128     let steps = create_steps(fcx, span, self_ty);
129
130     // Create a list of simplified self types, if we can.
131     let mut simplified_steps = Vec::new();
132     for step in steps.iter() {
133         match fast_reject::simplify_type(fcx.tcx(), step.self_ty, true) {
134             None => { break; }
135             Some(simplified_type) => { simplified_steps.push(simplified_type); }
136         }
137     }
138     let opt_simplified_steps =
139         if simplified_steps.len() < steps.len() {
140             None // failed to convert at least one of the steps
141         } else {
142             Some(simplified_steps)
143         };
144
145     debug!("ProbeContext: steps for self_ty={} are {}",
146            self_ty.repr(fcx.tcx()),
147            steps.repr(fcx.tcx()));
148
149     // this creates one big transaction so that all type variables etc
150     // that we create during the probe process are removed later
151     let mut dummy = Some((steps, opt_simplified_steps)); // FIXME(#18101) need once closures
152     fcx.infcx().probe(|| {
153         let (steps, opt_simplified_steps) = dummy.take().unwrap();
154         let mut probe_cx = ProbeContext::new(fcx, span, method_name, steps, opt_simplified_steps);
155         probe_cx.assemble_inherent_candidates();
156         probe_cx.assemble_extension_candidates_for_traits_in_scope(call_expr_id);
157         probe_cx.pick()
158     })
159 }
160
161 fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
162                           span: Span,
163                           self_ty: Ty<'tcx>)
164                           -> Vec<CandidateStep<'tcx>> {
165     let mut steps = Vec::new();
166
167     let (fully_dereferenced_ty, dereferences, _) =
168         check::autoderef(
169             fcx, span, self_ty, None, NoPreference,
170             |t, d| {
171                 let adjustment = consider_reborrow(t, d);
172                 steps.push(CandidateStep { self_ty: t, adjustment: adjustment });
173                 None::<()> // keep iterating until we can't anymore
174             });
175
176     match fully_dereferenced_ty.sty {
177         ty::ty_vec(elem_ty, Some(len)) => {
178             steps.push(CandidateStep {
179                 self_ty: ty::mk_vec(fcx.tcx(), elem_ty, None),
180                 adjustment: AutoUnsizeLength(dereferences, len),
181             });
182         }
183         _ => {
184         }
185     }
186
187     return steps;
188
189     fn consider_reborrow(ty: Ty, d: uint) -> PickAdjustment {
190         // Insert a `&*` or `&mut *` if this is a reference type:
191         match ty.sty {
192             ty::ty_rptr(_, ref mt) => AutoRef(mt.mutbl, box AutoDeref(d+1)),
193             _ => AutoDeref(d),
194         }
195     }
196 }
197
198 impl<'a,'tcx> ProbeContext<'a,'tcx> {
199     fn new(fcx: &'a FnCtxt<'a,'tcx>,
200            span: Span,
201            method_name: ast::Name,
202            steps: Vec<CandidateStep<'tcx>>,
203            opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>)
204            -> ProbeContext<'a,'tcx>
205     {
206         ProbeContext {
207             fcx: fcx,
208             span: span,
209             method_name: method_name,
210             inherent_candidates: Vec::new(),
211             extension_candidates: Vec::new(),
212             impl_dups: HashSet::new(),
213             steps: Rc::new(steps),
214             opt_simplified_steps: opt_simplified_steps,
215             static_candidates: Vec::new(),
216         }
217     }
218
219     fn tcx(&self) -> &'a ty::ctxt<'tcx> {
220         self.fcx.tcx()
221     }
222
223     fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
224         self.fcx.infcx()
225     }
226
227     ///////////////////////////////////////////////////////////////////////////
228     // CANDIDATE ASSEMBLY
229
230     fn assemble_inherent_candidates(&mut self) {
231         let steps = self.steps.clone();
232         for step in steps.iter() {
233             self.assemble_probe(step.self_ty);
234         }
235     }
236
237     fn assemble_probe(&mut self, self_ty: Ty<'tcx>) {
238         debug!("assemble_probe: self_ty={}",
239                self_ty.repr(self.tcx()));
240
241         match self_ty.sty {
242             ty::ty_trait(box ty::TyTrait { ref principal, bounds, .. }) => {
243                 self.assemble_inherent_candidates_from_object(self_ty, &*principal, bounds);
244                 self.assemble_inherent_impl_candidates_for_type(principal.def_id);
245             }
246             ty::ty_enum(did, _) |
247             ty::ty_struct(did, _) |
248             ty::ty_unboxed_closure(did, _, _) => {
249                 self.assemble_inherent_impl_candidates_for_type(did);
250             }
251             ty::ty_param(p) => {
252                 self.assemble_inherent_candidates_from_param(self_ty, p);
253             }
254             _ => {
255             }
256         }
257     }
258
259     fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) {
260         // Read the inherent implementation candidates for this type from the
261         // metadata if necessary.
262         ty::populate_implementations_for_type_if_necessary(self.tcx(), def_id);
263
264         for impl_infos in self.tcx().inherent_impls.borrow().get(&def_id).iter() {
265             for &impl_def_id in impl_infos.iter() {
266                 self.assemble_inherent_impl_probe(impl_def_id);
267             }
268         }
269     }
270
271     fn assemble_inherent_impl_probe(&mut self, impl_def_id: ast::DefId) {
272         if !self.impl_dups.insert(impl_def_id) {
273             return; // already visited
274         }
275
276         let method = match impl_method(self.tcx(), impl_def_id, self.method_name) {
277             Some(m) => m,
278             None => { return; } // No method with correct name on this impl
279         };
280
281         if !self.has_applicable_self(&*method) {
282             // No receiver declared. Not a candidate.
283             return self.record_static_candidate(ImplSource(impl_def_id));
284         }
285
286         let impl_substs = self.impl_substs(impl_def_id);
287
288         // Determine the receiver type that the method itself expects.
289         let xform_self_ty =
290             self.xform_self_ty(&method, &impl_substs);
291
292         self.inherent_candidates.push(Candidate {
293             xform_self_ty: xform_self_ty,
294             method_ty: method,
295             kind: InherentImplCandidate(impl_def_id, impl_substs)
296         });
297     }
298
299     fn assemble_inherent_candidates_from_object(&mut self,
300                                                 self_ty: Ty<'tcx>,
301                                                 principal: &ty::TraitRef<'tcx>,
302                                                 _bounds: ty::ExistentialBounds) {
303         debug!("assemble_inherent_candidates_from_object(self_ty={})",
304                self_ty.repr(self.tcx()));
305
306         let tcx = self.tcx();
307
308         // It is illegal to invoke a method on a trait instance that
309         // refers to the `Self` type. An error will be reported by
310         // `enforce_object_limitations()` if the method refers to the
311         // `Self` type anywhere other than the receiver. Here, we use
312         // a substitution that replaces `Self` with the object type
313         // itself. Hence, a `&self` method will wind up with an
314         // argument type like `&Trait`.
315         let rcvr_substs = principal.substs.clone().with_self_ty(self_ty);
316         let trait_ref = Rc::new(ty::TraitRef {
317             def_id: principal.def_id,
318             substs: rcvr_substs.clone()
319         });
320
321         self.elaborate_bounds(&[trait_ref.clone()], |this, new_trait_ref, m, method_num| {
322             let vtable_index =
323                 get_method_index(tcx, &*new_trait_ref,
324                                  trait_ref.clone(), method_num);
325
326             // FIXME Hacky. By-value `self` methods in objects ought to be
327             // just a special case of passing ownership of a DST value
328             // as a parameter. *But* we currently hack them in and tie them to
329             // the particulars of the `Box` type. So basically for a `fn foo(self,...)`
330             // method invoked on an object, we don't want the receiver type to be
331             // `TheTrait`, but rather `Box<TheTrait>`. Yuck.
332             let mut m = m;
333             match m.explicit_self {
334                 ty::ByValueExplicitSelfCategory => {
335                     let mut n = (*m).clone();
336                     let self_ty = n.fty.sig.inputs[0];
337                     n.fty.sig.inputs[0] = ty::mk_uniq(tcx, self_ty);
338                     m = Rc::new(n);
339                 }
340                 _ => { }
341             }
342
343             let xform_self_ty =
344                 this.xform_self_ty(&m, &new_trait_ref.substs);
345
346             this.inherent_candidates.push(Candidate {
347                 xform_self_ty: xform_self_ty,
348                 method_ty: m,
349                 kind: ObjectCandidate(MethodObject {
350                     trait_ref: new_trait_ref,
351                     object_trait_id: principal.def_id,
352                     method_num: method_num,
353                     real_index: vtable_index
354                 })
355             });
356         });
357     }
358
359     fn assemble_inherent_candidates_from_param(&mut self,
360                                                _rcvr_ty: Ty<'tcx>,
361                                                param_ty: ty::ParamTy) {
362         // FIXME -- Do we want to commit to this behavior for param bounds?
363
364         let ty::ParamTy { space, idx: index, .. } = param_ty;
365         let bounds =
366             self.fcx.inh.param_env.bounds.get(space, index).trait_bounds
367             .as_slice();
368         self.elaborate_bounds(bounds, |this, trait_ref, m, method_num| {
369             let xform_self_ty =
370                 this.xform_self_ty(&m, &trait_ref.substs);
371
372             debug!("found match: trait_ref={} substs={} m={}",
373                    trait_ref.repr(this.tcx()),
374                    trait_ref.substs.repr(this.tcx()),
375                    m.repr(this.tcx()));
376             assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
377                        trait_ref.substs.types.get_slice(subst::TypeSpace).len());
378             assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
379                        trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
380             assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
381                        trait_ref.substs.types.get_slice(subst::SelfSpace).len());
382             assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
383                        trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
384
385             // Because this trait derives from a where-clause, it
386             // should not contain any inference variables or other
387             // artifacts. This means it is safe to put into the
388             // `WhereClauseCandidate` and (eventually) into the
389             // `WhereClausePick`.
390             assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t)));
391
392             this.inherent_candidates.push(Candidate {
393                 xform_self_ty: xform_self_ty,
394                 method_ty: m,
395                 kind: WhereClauseCandidate(trait_ref, method_num)
396             });
397         });
398     }
399
400     // Do a search through a list of bounds, using a callback to actually
401     // create the candidates.
402     fn elaborate_bounds(
403         &mut self,
404         bounds: &[Rc<ty::TraitRef<'tcx>>],
405         mk_cand: for<'a> |this: &mut ProbeContext<'a, 'tcx>,
406                           tr: Rc<ty::TraitRef<'tcx>>,
407                           m: Rc<ty::Method<'tcx>>,
408                           method_num: uint|)
409     {
410         let tcx = self.tcx();
411         let mut cache = HashSet::new();
412         for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
413             // Already visited this trait, skip it.
414             if !cache.insert(bound_trait_ref.def_id) {
415                 continue;
416             }
417
418             let (pos, method) = match trait_method(tcx, bound_trait_ref.def_id, self.method_name) {
419                 Some(v) => v,
420                 None => { continue; }
421             };
422
423             if !self.has_applicable_self(&*method) {
424                 self.record_static_candidate(TraitSource(bound_trait_ref.def_id));
425             } else {
426                 mk_cand(self, bound_trait_ref, method, pos);
427             }
428         }
429     }
430
431     fn assemble_extension_candidates_for_traits_in_scope(&mut self,
432                                                          expr_id: ast::NodeId)
433     {
434         let mut duplicates = HashSet::new();
435         let opt_applicable_traits = self.fcx.ccx.trait_map.get(&expr_id);
436         for applicable_traits in opt_applicable_traits.into_iter() {
437             for &trait_did in applicable_traits.iter() {
438                 if duplicates.insert(trait_did) {
439                     self.assemble_extension_candidates_for_trait(trait_did);
440                 }
441             }
442         }
443     }
444
445     fn assemble_extension_candidates_for_trait(&mut self,
446                                            trait_def_id: ast::DefId) {
447         debug!("assemble_extension_candidates_for_trait: trait_def_id={}",
448                trait_def_id.repr(self.tcx()));
449
450         // Check whether `trait_def_id` defines a method with suitable name:
451         let trait_items =
452             ty::trait_items(self.tcx(), trait_def_id);
453         let matching_index =
454             trait_items.iter()
455                        .position(|item| item.name() == self.method_name);
456         let matching_index = match matching_index {
457             Some(i) => i,
458             None => { return; }
459         };
460         let method = match (&*trait_items)[matching_index].as_opt_method() {
461             Some(m) => m,
462             None => { return; }
463         };
464
465         // Check whether `trait_def_id` defines a method with suitable name:
466         if !self.has_applicable_self(&*method) {
467             debug!("method has inapplicable self");
468             return self.record_static_candidate(TraitSource(trait_def_id));
469         }
470
471         self.assemble_extension_candidates_for_trait_impls(trait_def_id,
472                                                            method.clone(),
473                                                            matching_index);
474
475         self.assemble_unboxed_closure_candidates(trait_def_id,
476                                                  method,
477                                                  matching_index);
478     }
479
480     fn assemble_extension_candidates_for_trait_impls(&mut self,
481                                                      trait_def_id: ast::DefId,
482                                                      method: Rc<ty::Method<'tcx>>,
483                                                      method_index: uint)
484     {
485         ty::populate_implementations_for_trait_if_necessary(self.tcx(),
486                                                             trait_def_id);
487
488         let trait_impls = self.tcx().trait_impls.borrow();
489         let impl_def_ids = match trait_impls.get(&trait_def_id) {
490             None => { return; }
491             Some(impls) => impls,
492         };
493
494         for &impl_def_id in impl_def_ids.borrow().iter() {
495             debug!("assemble_extension_candidates_for_trait_impl: trait_def_id={} impl_def_id={}",
496                    trait_def_id.repr(self.tcx()),
497                    impl_def_id.repr(self.tcx()));
498
499             if !self.impl_can_possibly_match(impl_def_id) {
500                 continue;
501             }
502
503             let impl_substs = self.impl_substs(impl_def_id);
504
505             debug!("impl_substs={}", impl_substs.repr(self.tcx()));
506
507             let impl_trait_ref =
508                 ty::impl_trait_ref(self.tcx(), impl_def_id)
509                 .unwrap() // we know this is a trait impl
510                 .subst(self.tcx(), &impl_substs);
511
512             debug!("impl_trait_ref={}", impl_trait_ref.repr(self.tcx()));
513
514             // Determine the receiver type that the method itself expects.
515             let xform_self_ty =
516                 self.xform_self_ty(&method, &impl_trait_ref.substs);
517
518             debug!("xform_self_ty={}", xform_self_ty.repr(self.tcx()));
519
520             self.extension_candidates.push(Candidate {
521                 xform_self_ty: xform_self_ty,
522                 method_ty: method.clone(),
523                 kind: ExtensionImplCandidate(impl_def_id, impl_trait_ref, impl_substs, method_index)
524             });
525         }
526     }
527
528     fn impl_can_possibly_match(&self, impl_def_id: ast::DefId) -> bool {
529         let simplified_steps = match self.opt_simplified_steps {
530             Some(ref simplified_steps) => simplified_steps,
531             None => { return true; }
532         };
533
534         let impl_type = ty::lookup_item_type(self.tcx(), impl_def_id);
535         let impl_simplified_type =
536             match fast_reject::simplify_type(self.tcx(), impl_type.ty, false) {
537                 Some(simplified_type) => simplified_type,
538                 None => { return true; }
539             };
540
541         simplified_steps.contains(&impl_simplified_type)
542     }
543
544     fn assemble_unboxed_closure_candidates(&mut self,
545                                            trait_def_id: ast::DefId,
546                                            method_ty: Rc<ty::Method<'tcx>>,
547                                            method_index: uint)
548     {
549         // Check if this is one of the Fn,FnMut,FnOnce traits.
550         let tcx = self.tcx();
551         let kind = if Some(trait_def_id) == tcx.lang_items.fn_trait() {
552             ty::FnUnboxedClosureKind
553         } else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
554             ty::FnMutUnboxedClosureKind
555         } else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
556             ty::FnOnceUnboxedClosureKind
557         } else {
558             return;
559         };
560
561         // Check if there is an unboxed-closure self-type in the list of receivers.
562         // If so, add "synthetic impls".
563         let steps = self.steps.clone();
564         for step in steps.iter() {
565             let (closure_def_id, _, _) = match step.self_ty.sty {
566                 ty::ty_unboxed_closure(a, b, ref c) => (a, b, c),
567                 _ => continue,
568             };
569
570             let unboxed_closures = self.fcx.inh.unboxed_closures.borrow();
571             let closure_data = match unboxed_closures.get(&closure_def_id) {
572                 Some(data) => data,
573                 None => {
574                     self.tcx().sess.span_bug(
575                         self.span,
576                         format!("No entry for unboxed closure: {}",
577                                 closure_def_id.repr(self.tcx())).as_slice());
578                 }
579             };
580
581             // this closure doesn't implement the right kind of `Fn` trait
582             if closure_data.kind != kind {
583                 continue;
584             }
585
586             // create some substitutions for the argument/return type;
587             // for the purposes of our method lookup, we only take
588             // receiver type into account, so we can just substitute
589             // fresh types here to use during substitution and subtyping.
590             let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
591             let substs = self.infcx().fresh_substs_for_trait(self.span,
592                                                              &trait_def.generics,
593                                                              step.self_ty);
594
595             let xform_self_ty = self.xform_self_ty(&method_ty, &substs);
596             self.inherent_candidates.push(Candidate {
597                 xform_self_ty: xform_self_ty,
598                 method_ty: method_ty.clone(),
599                 kind: UnboxedClosureCandidate(trait_def_id, method_index)
600             });
601         }
602     }
603
604     ///////////////////////////////////////////////////////////////////////////
605     // THE ACTUAL SEARCH
606
607     fn pick(mut self) -> PickResult<'tcx> {
608         let steps = self.steps.clone();
609
610         for step in steps.iter() {
611             match self.pick_step(step) {
612                 Some(r) => {
613                     return r;
614                 }
615                 None => { }
616             }
617         }
618
619         Err(NoMatch(self.static_candidates))
620     }
621
622     fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option<PickResult<'tcx>> {
623         debug!("pick_step: step={}", step.repr(self.tcx()));
624
625         if ty::type_is_error(step.self_ty) {
626             return None;
627         }
628
629         match self.pick_adjusted_method(step) {
630             Some(result) => return Some(result),
631             None => {}
632         }
633
634         match self.pick_autorefd_method(step) {
635             Some(result) => return Some(result),
636             None => {}
637         }
638
639         // FIXME -- Super hack. For DST types, we will convert to
640         // &&[T] or &&str, as part of a kind of legacy lookup scheme.
641         match step.self_ty.sty {
642             ty::ty_str | ty::ty_vec(_, None) => self.pick_autorefrefd_method(step),
643             _ => None
644         }
645     }
646
647     fn pick_adjusted_method(&mut self,
648                             step: &CandidateStep<'tcx>)
649                             -> Option<PickResult<'tcx>>
650     {
651         self.pick_method(step.self_ty).map(|r| self.adjust(r, step.adjustment.clone()))
652     }
653
654     fn pick_autorefd_method(&mut self,
655                             step: &CandidateStep<'tcx>)
656                             -> Option<PickResult<'tcx>>
657     {
658         let tcx = self.tcx();
659         self.search_mutabilities(
660             |m| AutoRef(m, box step.adjustment.clone()),
661             |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:step.self_ty, mutbl:m}))
662     }
663
664     fn pick_autorefrefd_method(&mut self,
665                                step: &CandidateStep<'tcx>)
666                                -> Option<PickResult<'tcx>>
667     {
668         let tcx = self.tcx();
669         self.search_mutabilities(
670             |m| AutoRef(m, box AutoRef(m, box step.adjustment.clone())),
671             |m,r| ty::mk_rptr(tcx, r, ty::mt { ty: ty::mk_rptr(tcx, r, ty::mt { ty:step.self_ty,
672                                                                                 mutbl:m}),
673                                                mutbl: m }))
674     }
675
676     fn search_mutabilities(&mut self,
677                            mk_adjustment: |ast::Mutability| -> PickAdjustment,
678                            mk_autoref_ty: |ast::Mutability, ty::Region| -> Ty<'tcx>)
679                            -> Option<PickResult<'tcx>>
680     {
681         // In general, during probing we erase regions. See
682         // `impl_self_ty()` for an explanation.
683         let region = ty::ReStatic;
684
685         // Search through mutabilities in order to find one where pick works:
686         [ast::MutImmutable, ast::MutMutable]
687             .iter()
688             .flat_map(|&m| {
689                 let autoref_ty = mk_autoref_ty(m, region);
690                 self.pick_method(autoref_ty)
691                     .map(|r| self.adjust(r, mk_adjustment(m)))
692                     .into_iter()
693             })
694             .nth(0)
695     }
696
697     fn adjust(&mut self,
698               result: PickResult<'tcx>,
699               adjustment: PickAdjustment)
700               -> PickResult<'tcx> {
701         match result {
702             Err(e) => Err(e),
703             Ok(mut pick) => {
704                 pick.adjustment = adjustment;
705                 Ok(pick)
706             }
707         }
708     }
709
710     fn pick_method(&mut self, self_ty: Ty<'tcx>) -> Option<PickResult<'tcx>> {
711         debug!("pick_method(self_ty={})", self.infcx().ty_to_string(self_ty));
712
713         debug!("searching inherent candidates");
714         match self.consider_candidates(self_ty, self.inherent_candidates[]) {
715             None => {}
716             Some(pick) => {
717                 return Some(pick);
718             }
719         }
720
721         debug!("searching extension candidates");
722         self.consider_candidates(self_ty, self.extension_candidates[])
723     }
724
725     fn consider_candidates(&self,
726                            self_ty: Ty<'tcx>,
727                            probes: &[Candidate<'tcx>])
728                            -> Option<PickResult<'tcx>> {
729         let mut applicable_candidates: Vec<_> =
730             probes.iter()
731                   .filter(|&probe| self.consider_probe(self_ty, probe))
732                   .collect();
733
734         debug!("applicable_candidates: {}", applicable_candidates.repr(self.tcx()));
735
736         if applicable_candidates.len() > 1 {
737             match self.collapse_candidates_to_trait_pick(applicable_candidates[]) {
738                 Some(pick) => { return Some(Ok(pick)); }
739                 None => { }
740             }
741         }
742
743         if applicable_candidates.len() > 1 {
744             let sources = probes.iter().map(|p| p.to_source()).collect();
745             return Some(Err(Ambiguity(sources)));
746         }
747
748         applicable_candidates.pop().map(|probe| {
749             let pick = probe.to_unadjusted_pick();
750             Ok(pick)
751         })
752     }
753
754     fn consider_probe(&self, self_ty: Ty<'tcx>, probe: &Candidate<'tcx>) -> bool {
755         debug!("consider_probe: self_ty={} probe={}",
756                self_ty.repr(self.tcx()),
757                probe.repr(self.tcx()));
758
759         self.infcx().probe(|| {
760             // First check that the self type can be related.
761             match self.make_sub_ty(self_ty, probe.xform_self_ty) {
762                 Ok(()) => { }
763                 Err(_) => {
764                     debug!("--> cannot relate self-types");
765                     return false;
766                 }
767             }
768
769             // If so, impls may carry other conditions (e.g., where
770             // clauses) that must be considered. Make sure that those
771             // match as well (or at least may match, sometimes we
772             // don't have enough information to fully evaluate).
773             match probe.kind {
774                 InherentImplCandidate(impl_def_id, ref substs) |
775                 ExtensionImplCandidate(impl_def_id, _, ref substs, _) => {
776                     // Check whether the impl imposes obligations we have to worry about.
777                     let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
778                     let impl_bounds = impl_generics.to_bounds(self.tcx(), substs);
779
780                     // Erase any late-bound regions bound in the impl
781                     // which appear in the bounds.
782                     let impl_bounds = self.erase_late_bound_regions(&ty::bind(impl_bounds)).value;
783
784                     // Convert the bounds into obligations.
785                     let obligations =
786                         traits::obligations_for_generics(
787                             self.tcx(),
788                             traits::ObligationCause::misc(self.span),
789                             &impl_bounds,
790                             &substs.types);
791                     debug!("impl_obligations={}", obligations.repr(self.tcx()));
792
793                     // Evaluate those obligations to see if they might possibly hold.
794                     let mut selcx = traits::SelectionContext::new(self.infcx(),
795                                                                   &self.fcx.inh.param_env,
796                                                                   self.fcx);
797                     obligations.all(|o| selcx.evaluate_obligation(o))
798                 }
799
800                 ObjectCandidate(..) |
801                 UnboxedClosureCandidate(..) |
802                 WhereClauseCandidate(..) => {
803                     // These have no additional conditions to check.
804                     true
805                 }
806             }
807         })
808     }
809
810     /// Sometimes we get in a situation where we have multiple probes that are all impls of the
811     /// same trait, but we don't know which impl to use. In this case, since in all cases the
812     /// external interface of the method can be determined from the trait, it's ok not to decide.
813     /// We can basically just collapse all of the probes for various impls into one where-clause
814     /// probe. This will result in a pending obligation so when more type-info is available we can
815     /// make the final decision.
816     ///
817     /// Example (`src/test/run-pass/method-two-trait-defer-resolution-1.rs`):
818     ///
819     /// ```
820     /// trait Foo { ... }
821     /// impl Foo for Vec<int> { ... }
822     /// impl Foo for Vec<uint> { ... }
823     /// ```
824     ///
825     /// Now imagine the receiver is `Vec<_>`. It doesn't really matter at this time which impl we
826     /// use, so it's ok to just commit to "using the method from the trait Foo".
827     fn collapse_candidates_to_trait_pick(&self,
828                                          probes: &[&Candidate<'tcx>])
829                                          -> Option<Pick<'tcx>> {
830         // Do all probes correspond to the same trait?
831         let trait_data = match probes[0].to_trait_data() {
832             Some(data) => data,
833             None => return None,
834         };
835         if probes[1..].iter().any(|p| p.to_trait_data() != Some(trait_data)) {
836             return None;
837         }
838
839         // If so, just use this trait and call it a day.
840         let (trait_def_id, method_num) = trait_data;
841         let method_ty = probes[0].method_ty.clone();
842         Some(Pick {
843             method_ty: method_ty,
844             adjustment: AutoDeref(0),
845             kind: TraitPick(trait_def_id, method_num)
846         })
847     }
848
849     ///////////////////////////////////////////////////////////////////////////
850     // MISCELLANY
851
852     fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::ures<'tcx> {
853         self.infcx().sub_types(false, infer::Misc(DUMMY_SP), sub, sup)
854     }
855
856     fn has_applicable_self(&self, method: &ty::Method) -> bool {
857         // "fast track" -- check for usage of sugar
858         match method.explicit_self {
859             ty::StaticExplicitSelfCategory => {
860                 // fallthrough
861             }
862             ty::ByValueExplicitSelfCategory |
863             ty::ByReferenceExplicitSelfCategory(..) |
864             ty::ByBoxExplicitSelfCategory => {
865                 return true;
866             }
867         }
868
869         // FIXME -- check for types that deref to `Self`,
870         // like `Rc<Self>` and so on.
871         //
872         // Note also that the current code will break if this type
873         // includes any of the type parameters defined on the method
874         // -- but this could be overcome.
875         return false;
876     }
877
878     fn record_static_candidate(&mut self, source: CandidateSource) {
879         self.static_candidates.push(source);
880     }
881
882     fn xform_self_ty(&self,
883                      method: &Rc<ty::Method<'tcx>>,
884                      substs: &subst::Substs<'tcx>)
885                      -> Ty<'tcx> {
886         debug!("xform_self_ty(self_ty={}, substs={})",
887                method.fty.sig.inputs[0].repr(self.tcx()),
888                substs.repr(self.tcx()));
889
890         // It is possible for type parameters or early-bound lifetimes
891         // to appear in the signature of `self`. The substitutions we
892         // are given do not include type/lifetime parameters for the
893         // method yet. So create fresh variables here for those too,
894         // if there are any.
895         assert_eq!(substs.types.len(subst::FnSpace), 0);
896         assert_eq!(substs.regions().len(subst::FnSpace), 0);
897         let mut substs = substs;
898         let placeholder;
899         if
900             !method.generics.types.is_empty_in(subst::FnSpace) ||
901             !method.generics.regions.is_empty_in(subst::FnSpace)
902         {
903             let method_types =
904                 self.infcx().next_ty_vars(
905                     method.generics.types.len(subst::FnSpace));
906
907             // In general, during probe we erase regions. See
908             // `impl_self_ty()` for an explanation.
909             let method_regions =
910                 method.generics.regions.get_slice(subst::FnSpace)
911                 .iter()
912                 .map(|_| ty::ReStatic)
913                 .collect();
914
915             placeholder = (*substs).clone().with_method(method_types, method_regions);
916             substs = &placeholder;
917         }
918
919         // Replace early-bound regions and types.
920         let xform_self_ty = method.fty.sig.inputs[0].subst(self.tcx(), substs);
921
922         // Replace late-bound regions bound in the impl or
923         // where-clause (2 levels of binding).
924         let xform_self_ty =
925             self.erase_late_bound_regions(&ty::bind(ty::bind(xform_self_ty))).value.value;
926
927         // Replace late-bound regions bound in the method (1 level of binding).
928         self.erase_late_bound_regions(&ty::bind(xform_self_ty)).value
929     }
930
931     fn impl_substs(&self,
932                    impl_def_id: ast::DefId)
933                    -> subst::Substs<'tcx>
934     {
935         let impl_pty = ty::lookup_item_type(self.tcx(), impl_def_id);
936
937         let type_vars =
938             impl_pty.generics.types.map(
939                 |_| self.infcx().next_ty_var());
940
941         let region_placeholders =
942             impl_pty.generics.regions.map(
943                 |_| ty::ReStatic); // see erase_late_bound_regions() for an expl of why 'static
944
945         subst::Substs::new(type_vars, region_placeholders)
946     }
947
948     /// Replace late-bound-regions bound by `value` with `'static` using
949     /// `ty::erase_late_bound_regions`.
950     ///
951     /// This is only a reasonable thing to do during the *probe* phase, not the *confirm* phase, of
952     /// method matching. It is reasonable during the probe phase because we don't consider region
953     /// relationships at all. Therefore, we can just replace all the region variables with 'static
954     /// rather than creating fresh region variables. This is nice for two reasons:
955     ///
956     /// 1. Because the numbers of the region variables would otherwise be fairly unique to this
957     ///    particular method call, it winds up creating fewer types overall, which helps for memory
958     ///    usage. (Admittedly, this is a rather small effect, though measureable.)
959     ///
960     /// 2. It makes it easier to deal with higher-ranked trait bounds, because we can replace any
961     ///    late-bound regions with 'static. Otherwise, if we were going to replace late-bound
962     ///    regions with actual region variables as is proper, we'd have to ensure that the same
963     ///    region got replaced with the same variable, which requires a bit more coordination
964     ///    and/or tracking the substitution and
965     ///    so forth.
966     fn erase_late_bound_regions<T>(&self, value: &T) -> T
967         where T : HigherRankedFoldable<'tcx>
968     {
969         ty::erase_late_bound_regions(self.tcx(), value)
970     }
971 }
972
973 fn impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
974                      impl_def_id: ast::DefId,
975                      method_name: ast::Name)
976                      -> Option<Rc<ty::Method<'tcx>>>
977 {
978     let impl_items = tcx.impl_items.borrow();
979     let impl_items = impl_items.get(&impl_def_id).unwrap();
980     impl_items
981         .iter()
982         .map(|&did| ty::impl_or_trait_item(tcx, did.def_id()))
983         .find(|m| m.name() == method_name)
984         .and_then(|item| item.as_opt_method())
985 }
986
987 /// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
988 /// index (or `None`, if no such method).
989 fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
990                       trait_def_id: ast::DefId,
991                       method_name: ast::Name)
992                       -> Option<(uint, Rc<ty::Method<'tcx>>)>
993 {
994     let trait_items = ty::trait_items(tcx, trait_def_id);
995     trait_items
996         .iter()
997         .enumerate()
998         .find(|&(_, ref item)| item.name() == method_name)
999         .and_then(|(idx, item)| item.as_opt_method().map(|m| (idx, m)))
1000 }
1001
1002 // Determine the index of a method in the list of all methods belonging
1003 // to a trait and its supertraits.
1004 fn get_method_index<'tcx>(tcx: &ty::ctxt<'tcx>,
1005                           trait_ref: &ty::TraitRef<'tcx>,
1006                           subtrait: Rc<ty::TraitRef<'tcx>>,
1007                           n_method: uint) -> uint {
1008     // We need to figure the "real index" of the method in a
1009     // listing of all the methods of an object. We do this by
1010     // iterating down the supertraits of the object's trait until
1011     // we find the trait the method came from, counting up the
1012     // methods from them.
1013     let mut method_count = 0;
1014     ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
1015         if bound_ref.def_id == trait_ref.def_id {
1016             false
1017         } else {
1018             let trait_items = ty::trait_items(tcx, bound_ref.def_id);
1019             for trait_item in trait_items.iter() {
1020                 match *trait_item {
1021                     ty::MethodTraitItem(_) => method_count += 1,
1022                     ty::TypeTraitItem(_) => {}
1023                 }
1024             }
1025             true
1026         }
1027     });
1028     method_count + n_method
1029 }
1030
1031 impl<'tcx> Candidate<'tcx> {
1032     fn to_unadjusted_pick(&self) -> Pick<'tcx> {
1033         Pick {
1034             method_ty: self.method_ty.clone(),
1035             adjustment: AutoDeref(0),
1036             kind: match self.kind {
1037                 InherentImplCandidate(def_id, _) => {
1038                     InherentImplPick(def_id)
1039                 }
1040                 ObjectCandidate(ref data) => {
1041                     ObjectPick(data.trait_ref.def_id, data.method_num, data.real_index)
1042                 }
1043                 ExtensionImplCandidate(def_id, _, _, index) => {
1044                     ExtensionImplPick(def_id, index)
1045                 }
1046                 UnboxedClosureCandidate(trait_def_id, index) => {
1047                     TraitPick(trait_def_id, index)
1048                 }
1049                 WhereClauseCandidate(ref trait_ref, index) => {
1050                     // Only trait derived from where-clauses should
1051                     // appear here, so they should not contain any
1052                     // inference variables or other artifacts. This
1053                     // means they are safe to put into the
1054                     // `WhereClausePick`.
1055                     assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t)));
1056
1057                     WhereClausePick((*trait_ref).clone(), index)
1058                 }
1059             }
1060         }
1061     }
1062
1063     fn to_source(&self) -> CandidateSource {
1064         match self.kind {
1065             InherentImplCandidate(def_id, _) => ImplSource(def_id),
1066             ObjectCandidate(ref obj) => TraitSource(obj.trait_ref.def_id),
1067             ExtensionImplCandidate(def_id, _, _, _) => ImplSource(def_id),
1068             UnboxedClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id),
1069             WhereClauseCandidate(ref trait_ref, _) => TraitSource(trait_ref.def_id),
1070         }
1071     }
1072
1073     fn to_trait_data(&self) -> Option<(ast::DefId,MethodIndex)> {
1074         match self.kind {
1075             InherentImplCandidate(..) |
1076             ObjectCandidate(..) => {
1077                 None
1078             }
1079             UnboxedClosureCandidate(trait_def_id, method_num) => {
1080                 Some((trait_def_id, method_num))
1081             }
1082             ExtensionImplCandidate(_, ref trait_ref, _, method_num) |
1083             WhereClauseCandidate(ref trait_ref, method_num) => {
1084                 Some((trait_ref.def_id, method_num))
1085             }
1086         }
1087     }
1088 }
1089
1090 impl<'tcx> Repr<'tcx> for Candidate<'tcx> {
1091     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1092         format!("Candidate(xform_self_ty={}, kind={})",
1093                 self.xform_self_ty.repr(tcx),
1094                 self.kind.repr(tcx))
1095     }
1096 }
1097
1098 impl<'tcx> Repr<'tcx> for CandidateKind<'tcx> {
1099     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1100         match *self {
1101             InherentImplCandidate(ref a, ref b) =>
1102                 format!("InherentImplCandidate({},{})", a.repr(tcx), b.repr(tcx)),
1103             ObjectCandidate(ref a) =>
1104                 format!("ObjectCandidate({})", a.repr(tcx)),
1105             ExtensionImplCandidate(ref a, ref b, ref c, ref d) =>
1106                 format!("ExtensionImplCandidate({},{},{},{})", a.repr(tcx), b.repr(tcx),
1107                         c.repr(tcx), d),
1108             UnboxedClosureCandidate(ref a, ref b) =>
1109                 format!("UnboxedClosureCandidate({},{})", a.repr(tcx), b),
1110             WhereClauseCandidate(ref a, ref b) =>
1111                 format!("WhereClauseCandidate({},{})", a.repr(tcx), b),
1112         }
1113     }
1114 }
1115
1116 impl<'tcx> Repr<'tcx> for CandidateStep<'tcx> {
1117     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1118         format!("CandidateStep({},{})",
1119                 self.self_ty.repr(tcx),
1120                 self.adjustment)
1121     }
1122 }
1123
1124 impl<'tcx> Repr<'tcx> for PickAdjustment {
1125     fn repr(&self, _tcx: &ty::ctxt) -> String {
1126         format!("{}", self)
1127     }
1128 }
1129
1130 impl<'tcx> Repr<'tcx> for PickKind<'tcx> {
1131     fn repr(&self, _tcx: &ty::ctxt) -> String {
1132         format!("{}", self)
1133     }
1134 }
1135
1136 impl<'tcx> Repr<'tcx> for Pick<'tcx> {
1137     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1138         format!("Pick(method_ty={}, adjustment={}, kind={})",
1139                 self.method_ty.repr(tcx),
1140                 self.adjustment,
1141                 self.kind)
1142     }
1143 }