]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/typeck/check/method.rs
Removed some unnecessary RefCells from resolve
[rust.git] / src / librustc / middle / typeck / check / method.rs
1 // Copyright 2012-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 /*!
12
13 # Method lookup
14
15 Method lookup can be rather complex due to the interaction of a number
16 of factors, such as self types, autoderef, trait lookup, etc.  The
17 algorithm is divided into two parts: candidate collection and
18 candidate selection.
19
20 ## Candidate collection
21
22 A `Candidate` is a method item that might plausibly be the method
23 being invoked.  Candidates are grouped into two kinds, inherent and
24 extension.  Inherent candidates are those that are derived from the
25 type of the receiver itself.  So, if you have a receiver of some
26 nominal type `Foo` (e.g., a struct), any methods defined within an
27 impl like `impl Foo` are inherent methods.  Nothing needs to be
28 imported to use an inherent method, they are associated with the type
29 itself (note that inherent impls can only be defined in the same
30 module as the type itself).
31
32 Inherent candidates are not always derived from impls.  If you have a
33 trait instance, such as a value of type `Box<ToString>`, then the trait
34 methods (`to_string()`, in this case) are inherently associated with it.
35 Another case is type parameters, in which case the methods of their
36 bounds are inherent.
37
38 Extension candidates are derived from imported traits.  If I have the
39 trait `ToString` imported, and I call `to_string()` on a value of type `T`,
40 then we will go off to find out whether there is an impl of `ToString`
41 for `T`.  These kinds of method calls are called "extension methods".
42 They can be defined in any module, not only the one that defined `T`.
43 Furthermore, you must import the trait to call such a method.
44
45 For better or worse, we currently give weight to inherent methods over
46 extension methods during candidate selection (below).
47
48 ## Candidate selection
49
50 Once we know the set of candidates, we can go off and try to select
51 which one is actually being called.  We do this by taking the type of
52 the receiver, let's call it R, and checking whether it matches against
53 the expected receiver type for each of the collected candidates.  We
54 first check for inherent candidates and see whether we get exactly one
55 match (zero means keep searching, more than one is an error).  If so,
56 we return that as the candidate.  Otherwise we search the extension
57 candidates in the same way.
58
59 If find no matching candidate at all, we proceed to auto-deref the
60 receiver type and search again.  We keep doing that until we cannot
61 auto-deref any longer.  At each step, we also check for candidates
62 based on "autoptr", which if the current type is `T`, checks for `&mut
63 T`, `&const T`, and `&T` receivers.  Finally, at the very end, we will
64 also try autoslice, which converts `~[]` to `&[]` (there is no point
65 at trying autoslice earlier, because no autoderefable type is also
66 sliceable).
67
68 ## Why two phases?
69
70 You might wonder why we first collect the candidates and then select.
71 Both the inherent candidate collection and the candidate selection
72 proceed by progressively deref'ing the receiver type, after all.  The
73 answer is that two phases are needed to elegantly deal with explicit
74 self.  After all, if there is an impl for the type `Foo`, it can
75 define a method with the type `Box<self>`, which means that it expects a
76 receiver of type `Box<Foo>`.  If we have a receiver of type `Box<Foo>`, but we
77 waited to search for that impl until we have deref'd the `Box` away and
78 obtained the type `Foo`, we would never match this method.
79
80 */
81
82
83 use middle::subst;
84 use middle::subst::Subst;
85 use middle::traits;
86 use middle::ty::*;
87 use middle::ty;
88 use middle::typeck::astconv::AstConv;
89 use middle::typeck::check::{FnCtxt, PreferMutLvalue, impl_self_ty};
90 use middle::typeck::check;
91 use middle::typeck::infer;
92 use middle::typeck::MethodCallee;
93 use middle::typeck::{MethodOrigin, MethodParam, MethodTypeParam};
94 use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject, MethodTraitObject};
95 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
96 use middle::typeck::TypeAndSubsts;
97 use util::common::indenter;
98 use util::ppaux;
99 use util::ppaux::Repr;
100
101 use std::collections::HashSet;
102 use std::rc::Rc;
103 use syntax::ast::{DefId, MutImmutable, MutMutable};
104 use syntax::ast;
105 use syntax::codemap::Span;
106 use syntax::parse::token;
107
108 #[deriving(PartialEq)]
109 pub enum CheckTraitsFlag {
110     CheckTraitsOnly,
111     CheckTraitsAndInherentMethods,
112 }
113
114 #[deriving(PartialEq)]
115 pub enum AutoderefReceiverFlag {
116     AutoderefReceiver,
117     DontAutoderefReceiver,
118 }
119
120 #[deriving(PartialEq)]
121 pub enum StaticMethodsFlag {
122     ReportStaticMethods,
123     IgnoreStaticMethods,
124 }
125
126 pub fn lookup<'a, 'tcx>(
127         fcx: &'a FnCtxt<'a, 'tcx>,
128
129         // In a call `a.b::<X, Y, ...>(...)`:
130         expr: &ast::Expr,                   // The expression `a.b(...)`.
131         self_expr: &'a ast::Expr,           // The expression `a`.
132         m_name: ast::Name,                  // The name `b`.
133         self_ty: ty::t,                     // The type of `a`.
134         supplied_tps: &'a [ty::t],          // The list of types X, Y, ... .
135         deref_args: check::DerefArgs,       // Whether we autopointer first.
136         check_traits: CheckTraitsFlag,      // Whether we check traits only.
137         autoderef_receiver: AutoderefReceiverFlag,
138         report_statics: StaticMethodsFlag)
139      -> Option<MethodCallee> {
140     let mut lcx = LookupContext {
141         fcx: fcx,
142         span: expr.span,
143         self_expr: Some(self_expr),
144         m_name: m_name,
145         supplied_tps: supplied_tps,
146         impl_dups: HashSet::new(),
147         inherent_candidates: Vec::new(),
148         extension_candidates: Vec::new(),
149         deref_args: deref_args,
150         check_traits: check_traits,
151         autoderef_receiver: autoderef_receiver,
152         report_statics: report_statics,
153     };
154
155     debug!("method lookup(self_ty={}, expr={}, self_expr={})",
156            self_ty.repr(fcx.tcx()), expr.repr(fcx.tcx()),
157            self_expr.repr(fcx.tcx()));
158
159     debug!("searching inherent candidates");
160     lcx.push_inherent_candidates(self_ty);
161     debug!("searching extension candidates");
162     lcx.push_bound_candidates(self_ty, None);
163     lcx.push_extension_candidates(expr.id);
164     lcx.search(self_ty)
165 }
166
167 pub fn lookup_in_trait<'a, 'tcx>(
168         fcx: &'a FnCtxt<'a, 'tcx>,
169
170         // In a call `a.b::<X, Y, ...>(...)`:
171         span: Span,                         // The expression `a.b(...)`'s span.
172         self_expr: Option<&'a ast::Expr>,   // The expression `a`, if available.
173         m_name: ast::Name,                  // The name `b`.
174         trait_did: DefId,                   // The trait to limit the lookup to.
175         self_ty: ty::t,                     // The type of `a`.
176         supplied_tps: &'a [ty::t],          // The list of types X, Y, ... .
177         autoderef_receiver: AutoderefReceiverFlag,
178         report_statics: StaticMethodsFlag)
179      -> Option<MethodCallee> {
180     let mut lcx = LookupContext {
181         fcx: fcx,
182         span: span,
183         self_expr: self_expr,
184         m_name: m_name,
185         supplied_tps: supplied_tps,
186         impl_dups: HashSet::new(),
187         inherent_candidates: Vec::new(),
188         extension_candidates: Vec::new(),
189         deref_args: check::DoDerefArgs,
190         check_traits: CheckTraitsOnly,
191         autoderef_receiver: autoderef_receiver,
192         report_statics: report_statics,
193     };
194
195     debug!("method lookup_in_trait(self_ty={}, self_expr={})",
196            self_ty.repr(fcx.tcx()), self_expr.map(|e| e.repr(fcx.tcx())));
197
198     lcx.push_bound_candidates(self_ty, Some(trait_did));
199     lcx.push_extension_candidate(trait_did);
200     lcx.search(self_ty)
201 }
202
203 // Determine the index of a method in the list of all methods belonging
204 // to a trait and its supertraits.
205 fn get_method_index(tcx: &ty::ctxt,
206                     trait_ref: &TraitRef,
207                     subtrait: Rc<TraitRef>,
208                     n_method: uint) -> uint {
209     // We need to figure the "real index" of the method in a
210     // listing of all the methods of an object. We do this by
211     // iterating down the supertraits of the object's trait until
212     // we find the trait the method came from, counting up the
213     // methods from them.
214     let mut method_count = 0;
215     ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
216         if bound_ref.def_id == trait_ref.def_id {
217             false
218         } else {
219             let trait_items = ty::trait_items(tcx, bound_ref.def_id);
220             for trait_item in trait_items.iter() {
221                 match *trait_item {
222                     ty::MethodTraitItem(_) => method_count += 1,
223                     ty::TypeTraitItem(_) => {}
224                 }
225             }
226             true
227         }
228     });
229     method_count + n_method
230 }
231
232 fn construct_transformed_self_ty_for_object(
233     tcx: &ty::ctxt,
234     span: Span,
235     trait_def_id: ast::DefId,
236     rcvr_substs: &subst::Substs,
237     rcvr_bounds: ty::ExistentialBounds,
238     method_ty: &ty::Method)
239     -> ty::t
240 {
241     /*!
242      * This is a bit tricky. We have a match against a trait method
243      * being invoked on an object, and we want to generate the
244      * self-type. As an example, consider a trait
245      *
246      *     trait Foo {
247      *         fn r_method<'a>(&'a self);
248      *         fn u_method(Box<self>);
249      *     }
250      *
251      * Now, assuming that `r_method` is being called, we want the
252      * result to be `&'a Foo`. Assuming that `u_method` is being
253      * called, we want the result to be `Box<Foo>`. Of course,
254      * this transformation has already been done as part of
255      * `method_ty.fty.sig.inputs[0]`, but there the type
256      * is expressed in terms of `Self` (i.e., `&'a Self`, `Box<Self>`).
257      * Because objects are not standalone types, we can't just substitute
258      * `s/Self/Foo/`, so we must instead perform this kind of hokey
259      * match below.
260      */
261
262     let mut obj_substs = rcvr_substs.clone();
263
264     // The subst we get in has Err as the "Self" type. For an object
265     // type, we don't put any type into the Self paramspace, so let's
266     // make a copy of rcvr_substs that has the Self paramspace empty.
267     obj_substs.types.pop(subst::SelfSpace).unwrap();
268
269     match method_ty.explicit_self {
270         StaticExplicitSelfCategory => {
271             tcx.sess.span_bug(span, "static method for object type receiver");
272         }
273         ByValueExplicitSelfCategory => {
274             let tr = ty::mk_trait(tcx, trait_def_id, obj_substs, rcvr_bounds);
275             ty::mk_uniq(tcx, tr)
276         }
277         ByReferenceExplicitSelfCategory(..) | ByBoxExplicitSelfCategory => {
278             let transformed_self_ty = *method_ty.fty.sig.inputs.get(0);
279             match ty::get(transformed_self_ty).sty {
280                 ty::ty_rptr(r, mt) => { // must be SelfRegion
281                     let r = r.subst(tcx, rcvr_substs); // handle Early-Bound lifetime
282                     let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
283                                           rcvr_bounds);
284                     ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: mt.mutbl })
285                 }
286                 ty::ty_uniq(_) => { // must be SelfUniq
287                     let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
288                                           rcvr_bounds);
289                     ty::mk_uniq(tcx, tr)
290                 }
291                 _ => {
292                     tcx.sess.span_bug(span,
293                         format!("'impossible' transformed_self_ty: {}",
294                                 transformed_self_ty.repr(tcx)).as_slice());
295                 }
296             }
297         }
298     }
299 }
300
301 struct LookupContext<'a, 'tcx: 'a> {
302     fcx: &'a FnCtxt<'a, 'tcx>,
303     span: Span,
304
305     // The receiver to the method call. Only `None` in the case of
306     // an overloaded autoderef, where the receiver may be an intermediate
307     // state like "the expression `x` when it has been autoderef'd
308     // twice already".
309     self_expr: Option<&'a ast::Expr>,
310
311     m_name: ast::Name,
312     supplied_tps: &'a [ty::t],
313     impl_dups: HashSet<DefId>,
314     inherent_candidates: Vec<Candidate>,
315     extension_candidates: Vec<Candidate>,
316     deref_args: check::DerefArgs,
317     check_traits: CheckTraitsFlag,
318     autoderef_receiver: AutoderefReceiverFlag,
319     report_statics: StaticMethodsFlag,
320 }
321
322 /**
323  * A potential method that might be called, assuming the receiver
324  * is of a suitable type.
325  */
326 #[deriving(Clone)]
327 struct Candidate {
328     rcvr_match_condition: RcvrMatchCondition,
329     rcvr_substs: subst::Substs,
330     method_ty: Rc<ty::Method>,
331     origin: MethodOrigin,
332 }
333
334 /// This type represents the conditions under which the receiver is
335 /// considered to "match" a given method candidate. Typically the test
336 /// is whether the receiver is of a particular type. However, this
337 /// type is the type of the receiver *after accounting for the
338 /// method's self type* (e.g., if the method is an `Box<self>` method, we
339 /// have *already verified* that the receiver is of some type `Box<T>` and
340 /// now we must check that the type `T` is correct).  Unfortunately,
341 /// because traits are not types, this is a pain to do.
342 #[deriving(Clone)]
343 pub enum RcvrMatchCondition {
344     RcvrMatchesIfObject(ast::DefId),
345     RcvrMatchesIfSubtype(ty::t),
346     RcvrMatchesIfEqtype(ty::t)
347 }
348
349 impl<'a, 'tcx> LookupContext<'a, 'tcx> {
350     fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {
351         let span = self.self_expr.map_or(self.span, |e| e.span);
352         let self_expr_id = self.self_expr.map(|e| e.id);
353
354         let (_, _, result) =
355             check::autoderef(
356                 self.fcx, span, self_ty, self_expr_id, PreferMutLvalue,
357                 |self_ty, autoderefs| self.search_step(self_ty, autoderefs));
358
359         match result {
360             Some(Some(result)) => Some(result),
361             _ => None
362         }
363     }
364
365     fn search_step(&self,
366                    self_ty: ty::t,
367                    autoderefs: uint)
368                    -> Option<Option<MethodCallee>> {
369         debug!("search_step: self_ty={} autoderefs={}",
370                self.ty_to_string(self_ty), autoderefs);
371
372         match self.deref_args {
373             check::DontDerefArgs => {
374                 match self.search_for_autoderefd_method(self_ty, autoderefs) {
375                     Some(result) => return Some(Some(result)),
376                     None => {}
377                 }
378
379                 match self.search_for_autoptrd_method(self_ty, autoderefs) {
380                     Some(result) => return Some(Some(result)),
381                     None => {}
382                 }
383             }
384             check::DoDerefArgs => {
385                 match self.search_for_autoptrd_method(self_ty, autoderefs) {
386                     Some(result) => return Some(Some(result)),
387                     None => {}
388                 }
389
390                 match self.search_for_autoderefd_method(self_ty, autoderefs) {
391                     Some(result) => return Some(Some(result)),
392                     None => {}
393                 }
394             }
395         }
396
397         // If we are searching for an overloaded deref, no
398         // need to try coercing a `~[T]` to an `&[T]` and
399         // searching for an overloaded deref on *that*.
400         if !self.is_overloaded_deref() {
401             match self.search_for_autofatptrd_method(self_ty, autoderefs) {
402                 Some(result) => return Some(Some(result)),
403                 None => {}
404             }
405         }
406
407         // Don't autoderef if we aren't supposed to.
408         if self.autoderef_receiver == DontAutoderefReceiver {
409             Some(None)
410         } else {
411             None
412         }
413     }
414
415     fn is_overloaded_deref(&self) -> bool {
416         self.self_expr.is_none()
417     }
418
419     // ______________________________________________________________________
420     // Candidate collection (see comment at start of file)
421
422     fn push_inherent_candidates(&mut self, self_ty: ty::t) {
423         /*!
424          * Collect all inherent candidates into
425          * `self.inherent_candidates`.  See comment at the start of
426          * the file.  To find the inherent candidates, we repeatedly
427          * deref the self-ty to find the "base-type".  So, for
428          * example, if the receiver is Box<Box<C>> where `C` is a struct type,
429          * we'll want to find the inherent impls for `C`.
430          */
431
432         let span = self.self_expr.map_or(self.span, |e| e.span);
433         check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
434             match get(self_ty).sty {
435                 ty_trait(box TyTrait { def_id, ref substs, bounds, .. }) => {
436                     self.push_inherent_candidates_from_object(
437                         def_id, substs, bounds);
438                     self.push_inherent_impl_candidates_for_type(def_id);
439                 }
440                 ty_enum(did, _) |
441                 ty_struct(did, _) |
442                 ty_unboxed_closure(did, _) => {
443                     if self.check_traits == CheckTraitsAndInherentMethods {
444                         self.push_inherent_impl_candidates_for_type(did);
445                     }
446                 }
447                 _ => { /* No inherent methods in these types */ }
448             }
449
450             // Don't autoderef if we aren't supposed to.
451             if self.autoderef_receiver == DontAutoderefReceiver {
452                 Some(())
453             } else {
454                 None
455             }
456         });
457     }
458
459     fn push_bound_candidates(&mut self, self_ty: ty::t, restrict_to: Option<DefId>) {
460         let span = self.self_expr.map_or(self.span, |e| e.span);
461         check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
462             match get(self_ty).sty {
463                 ty_param(p) => {
464                     self.push_inherent_candidates_from_param(self_ty, restrict_to, p);
465                 }
466                 ty_unboxed_closure(closure_did, _) => {
467                     self.push_unboxed_closure_call_candidates_if_applicable(
468                         closure_did);
469                 }
470                 _ => { /* No bound methods in these types */ }
471             }
472
473             // Don't autoderef if we aren't supposed to.
474             if self.autoderef_receiver == DontAutoderefReceiver {
475                 Some(())
476             } else {
477                 None
478             }
479         });
480     }
481
482     fn push_extension_candidate(&mut self, trait_did: DefId) {
483         ty::populate_implementations_for_trait_if_necessary(self.tcx(), trait_did);
484
485         // Look for explicit implementations.
486         let impl_items = self.tcx().impl_items.borrow();
487         for impl_infos in self.tcx().trait_impls.borrow().find(&trait_did).iter() {
488             for impl_did in impl_infos.borrow().iter() {
489                 let items = impl_items.get(impl_did);
490                 self.push_candidates_from_impl(*impl_did,
491                                                items.as_slice(),
492                                                true);
493             }
494         }
495     }
496
497     fn push_extension_candidates(&mut self, expr_id: ast::NodeId) {
498         // If the method being called is associated with a trait, then
499         // find all the impls of that trait.  Each of those are
500         // candidates.
501         let opt_applicable_traits = self.fcx.ccx.trait_map.find(&expr_id);
502         for applicable_traits in opt_applicable_traits.into_iter() {
503             for trait_did in applicable_traits.iter() {
504                 debug!("push_extension_candidates() found trait: {}",
505                        if trait_did.krate == ast::LOCAL_CRATE {
506                            self.fcx.ccx.tcx.map.node_to_string(trait_did.node)
507                        } else {
508                            "(external)".to_string()
509                        });
510                 self.push_extension_candidate(*trait_did);
511             }
512         }
513     }
514
515     fn push_unboxed_closure_call_candidate_if_applicable(
516             &mut self,
517             trait_did: DefId,
518             closure_did: DefId,
519             closure_function_type: &ClosureTy) {
520         let trait_item = ty::trait_items(self.tcx(), trait_did).get(0)
521                                                                .clone();
522         let method = match trait_item {
523             ty::MethodTraitItem(method) => method,
524             ty::TypeTraitItem(_) => {
525                 self.tcx().sess.bug(
526                     "push_unboxed_closure_call_candidates_if_applicable(): \
527                      unexpected associated type in function trait")
528             }
529         };
530
531         // Make sure it has the right name!
532         if method.ident.name != self.m_name {
533             return
534         }
535
536         // Get the tupled type of the arguments.
537         let arguments_type = *closure_function_type.sig.inputs.get(0);
538         let return_type = closure_function_type.sig.output;
539
540         let closure_region =
541             self.fcx.infcx().next_region_var(infer::MiscVariable(self.span));
542         let unboxed_closure_type = ty::mk_unboxed_closure(self.tcx(),
543                                                           closure_did,
544                                                           closure_region);
545         self.extension_candidates.push(Candidate {
546             rcvr_match_condition:
547                 RcvrMatchesIfSubtype(unboxed_closure_type),
548             rcvr_substs: subst::Substs::new_trait(
549                 vec![arguments_type, return_type],
550                 vec![],
551                 *self.fcx.infcx().next_ty_vars(1).get(0)),
552             method_ty: method,
553             origin: MethodStaticUnboxedClosure(closure_did),
554         });
555     }
556
557     fn push_unboxed_closure_call_candidates_if_applicable(
558             &mut self,
559             closure_did: DefId) {
560         match self.tcx().unboxed_closures.borrow().find(&closure_did) {
561             None => {}  // Fall through to try inherited.
562             Some(closure) => {
563                 let tcx = self.tcx();
564                 self.push_unboxed_closure_call_candidate_if_applicable(
565                     closure.kind.trait_did(tcx),
566                     closure_did,
567                     &closure.closure_type);
568                 return
569             }
570         }
571
572         match self.fcx.inh.unboxed_closures.borrow().find(&closure_did) {
573             Some(closure) => {
574                 let tcx = self.tcx();
575                 self.push_unboxed_closure_call_candidate_if_applicable(
576                     closure.kind.trait_did(tcx),
577                     closure_did,
578                     &closure.closure_type);
579                 return
580             }
581             None => {}
582         }
583
584         self.tcx().sess.bug("didn't find unboxed closure type in tcx map or \
585                              inherited map, so there")
586     }
587
588     fn push_inherent_candidates_from_object(&mut self,
589                                             did: DefId,
590                                             substs: &subst::Substs,
591                                             bounds: ty::ExistentialBounds) {
592         debug!("push_inherent_candidates_from_object(did={}, substs={})",
593                self.did_to_string(did),
594                substs.repr(self.tcx()));
595         let tcx = self.tcx();
596         let span = self.span;
597
598         // It is illegal to invoke a method on a trait instance that
599         // refers to the `self` type. An error will be reported by
600         // `enforce_object_limitations()` if the method refers
601         // to the `Self` type. Substituting ty_err here allows
602         // compiler to soldier on.
603         //
604         // `confirm_candidate()` also relies upon this substitution
605         // for Self. (fix)
606         let rcvr_substs = substs.with_self_ty(ty::mk_err());
607         let trait_ref = Rc::new(TraitRef {
608             def_id: did,
609             substs: rcvr_substs.clone()
610         });
611
612         self.push_inherent_candidates_from_bounds_inner(
613             &[trait_ref.clone()],
614             |_this, new_trait_ref, m, method_num| {
615                 let vtable_index =
616                     get_method_index(tcx, &*new_trait_ref,
617                                      trait_ref.clone(), method_num);
618                 let mut m = (*m).clone();
619                 // We need to fix up the transformed self type.
620                 *m.fty.sig.inputs.get_mut(0) =
621                     construct_transformed_self_ty_for_object(
622                         tcx, span, did, &rcvr_substs, bounds, &m);
623
624                 Some(Candidate {
625                     rcvr_match_condition: RcvrMatchesIfObject(did),
626                     rcvr_substs: new_trait_ref.substs.clone(),
627                     method_ty: Rc::new(m),
628                     origin: MethodTraitObject(MethodObject {
629                         trait_ref: new_trait_ref,
630                         object_trait_id: did,
631                         method_num: method_num,
632                         real_index: vtable_index
633                     })
634                 })
635             });
636     }
637
638     fn push_inherent_candidates_from_param(&mut self,
639                                            rcvr_ty: ty::t,
640                                            restrict_to: Option<DefId>,
641                                            param_ty: ParamTy) {
642         debug!("push_inherent_candidates_from_param(param_ty={:?})",
643                param_ty);
644         self.push_inherent_candidates_from_bounds(
645             rcvr_ty,
646             param_ty.space,
647             param_ty.idx,
648             restrict_to);
649     }
650
651
652     fn push_inherent_candidates_from_bounds(&mut self,
653                                             self_ty: ty::t,
654                                             space: subst::ParamSpace,
655                                             index: uint,
656                                             restrict_to: Option<DefId>) {
657         let bounds =
658             self.fcx.inh.param_env.bounds.get(space, index).trait_bounds
659             .as_slice();
660         self.push_inherent_candidates_from_bounds_inner(bounds,
661             |this, trait_ref, m, method_num| {
662                 match restrict_to {
663                     Some(trait_did) => {
664                         if trait_did != trait_ref.def_id {
665                             return None;
666                         }
667                     }
668                     _ => {}
669                 }
670
671                 let condition = match m.explicit_self {
672                     ByReferenceExplicitSelfCategory(_, mt) if mt == MutMutable =>
673                         RcvrMatchesIfEqtype(self_ty),
674                     _ =>
675                         RcvrMatchesIfSubtype(self_ty)
676                 };
677
678                 debug!("found match: trait_ref={} substs={} m={}",
679                        trait_ref.repr(this.tcx()),
680                        trait_ref.substs.repr(this.tcx()),
681                        m.repr(this.tcx()));
682                 assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
683                            trait_ref.substs.types.get_slice(subst::TypeSpace).len());
684                 assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
685                            trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
686                 assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
687                            trait_ref.substs.types.get_slice(subst::SelfSpace).len());
688                 assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
689                            trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
690                 Some(Candidate {
691                     rcvr_match_condition: condition,
692                     rcvr_substs: trait_ref.substs.clone(),
693                     method_ty: m,
694                     origin: MethodTypeParam(MethodParam {
695                         trait_ref: trait_ref,
696                         method_num: method_num,
697                     })
698                 })
699         })
700     }
701
702     // Do a search through a list of bounds, using a callback to actually
703     // create the candidates.
704     fn push_inherent_candidates_from_bounds_inner(
705         &mut self,
706         bounds: &[Rc<TraitRef>],
707         mk_cand: |this: &mut LookupContext,
708                   tr: Rc<TraitRef>,
709                   m: Rc<ty::Method>,
710                   method_num: uint|
711                   -> Option<Candidate>)
712     {
713         let tcx = self.tcx();
714         let mut cache = HashSet::new();
715         for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
716             // Already visited this trait, skip it.
717             if !cache.insert(bound_trait_ref.def_id) {
718                 continue;
719             }
720
721             let trait_items = ty::trait_items(tcx, bound_trait_ref.def_id);
722             match trait_items.iter().position(|ti| {
723                 match *ti {
724                     ty::MethodTraitItem(ref m) => {
725                         m.explicit_self != ty::StaticExplicitSelfCategory &&
726                         m.ident.name == self.m_name
727                     }
728                     ty::TypeTraitItem(_) => false,
729                 }
730             }) {
731                 Some(pos) => {
732                     let method = match *trait_items.get(pos) {
733                         ty::MethodTraitItem(ref method) => (*method).clone(),
734                         ty::TypeTraitItem(_) => {
735                             tcx.sess.bug("typechecking associated type as \
736                                           though it were a method")
737                         }
738                     };
739
740                     match mk_cand(self,
741                                   bound_trait_ref,
742                                   method,
743                                   pos) {
744                         Some(cand) => {
745                             debug!("pushing inherent candidate for param: {}",
746                                    cand.repr(self.tcx()));
747                             self.inherent_candidates.push(cand);
748                         }
749                         None => {}
750                     }
751                 }
752                 None => {
753                     debug!("trait doesn't contain method: {:?}",
754                         bound_trait_ref.def_id);
755                     // check next trait or bound
756                 }
757             }
758         }
759     }
760
761
762     fn push_inherent_impl_candidates_for_type(&mut self, did: DefId) {
763         // Read the inherent implementation candidates for this type from the
764         // metadata if necessary.
765         ty::populate_implementations_for_type_if_necessary(self.tcx(), did);
766
767         let impl_items = self.tcx().impl_items.borrow();
768         for impl_infos in self.tcx().inherent_impls.borrow().find(&did).iter() {
769             for impl_did in impl_infos.iter() {
770                 let items = impl_items.get(impl_did);
771                 self.push_candidates_from_impl(*impl_did,
772                                                items.as_slice(),
773                                                false);
774             }
775         }
776     }
777
778     fn push_candidates_from_impl(&mut self,
779                                  impl_did: DefId,
780                                  impl_items: &[ImplOrTraitItemId],
781                                  is_extension: bool) {
782         let did = if self.report_statics == ReportStaticMethods {
783             // we only want to report each base trait once
784             match ty::impl_trait_ref(self.tcx(), impl_did) {
785                 Some(trait_ref) => trait_ref.def_id,
786                 None => impl_did
787             }
788         } else {
789             impl_did
790         };
791
792         if !self.impl_dups.insert(did) {
793             return; // already visited
794         }
795
796         debug!("push_candidates_from_impl: {} {}",
797                token::get_name(self.m_name),
798                impl_items.iter()
799                          .map(|&did| {
800                              ty::impl_or_trait_item(self.tcx(),
801                                                     did.def_id()).ident()
802                          })
803                          .collect::<Vec<ast::Ident>>()
804                          .repr(self.tcx()));
805
806         let method = match impl_items.iter()
807                                      .map(|&did| {
808                                          ty::impl_or_trait_item(self.tcx(),
809                                                                 did.def_id())
810                                      })
811                                      .find(|m| {
812                                          m.ident().name == self.m_name
813                                      }) {
814             Some(ty::MethodTraitItem(method)) => method,
815             Some(ty::TypeTraitItem(_)) | None => {
816                 // No method with the right name.
817                 return
818             }
819         };
820
821         // determine the `self` of the impl with fresh
822         // variables for each parameter:
823         let span = self.self_expr.map_or(self.span, |e| e.span);
824         let TypeAndSubsts {
825             substs: impl_substs,
826             ty: impl_ty
827         } = impl_self_ty(self.fcx, span, impl_did);
828
829         let condition = match method.explicit_self {
830             ByReferenceExplicitSelfCategory(_, mt) if mt == MutMutable =>
831                 RcvrMatchesIfEqtype(impl_ty),
832             _ =>
833                 RcvrMatchesIfSubtype(impl_ty)
834         };
835
836         let candidates = if is_extension {
837             &mut self.extension_candidates
838         } else {
839             &mut self.inherent_candidates
840         };
841
842         candidates.push(Candidate {
843             rcvr_match_condition: condition,
844             rcvr_substs: impl_substs,
845             origin: MethodStatic(method.def_id),
846             method_ty: method,
847         });
848     }
849
850     // ______________________________________________________________________
851     // Candidate selection (see comment at start of file)
852
853     fn search_for_autoderefd_method(&self,
854                                     self_ty: ty::t,
855                                     autoderefs: uint)
856                                     -> Option<MethodCallee> {
857         // Hacky. For overloaded derefs, there may be an adjustment
858         // added to the expression from the outside context, so we do not store
859         // an explicit adjustment, but rather we hardwire the single deref
860         // that occurs in trans and mem_categorization.
861         if self.self_expr.is_none() {
862             return None;
863         }
864
865         let (self_ty, auto_deref_ref) = self.consider_reborrow(self_ty, autoderefs);
866         let adjustment = Some((self.self_expr.unwrap().id, ty::AdjustDerefRef(auto_deref_ref)));
867
868         match self.search_for_method(self_ty) {
869             None => None,
870             Some(method) => {
871                 debug!("(searching for autoderef'd method) writing \
872                        adjustment {:?} for {}", adjustment, self.ty_to_string(self_ty));
873                 match adjustment {
874                     Some((self_expr_id, adj)) => {
875                         self.fcx.write_adjustment(self_expr_id, self.span, adj);
876                     }
877                     None => {}
878                 }
879                 Some(method)
880             }
881         }
882     }
883
884     fn consider_reborrow(&self,
885                          self_ty: ty::t,
886                          autoderefs: uint)
887                          -> (ty::t, ty::AutoDerefRef) {
888         /*!
889          * In the event that we are invoking a method with a receiver
890          * of a borrowed type like `&T`, `&mut T`, or `&mut [T]`,
891          * we will "reborrow" the receiver implicitly.  For example, if
892          * you have a call `r.inc()` and where `r` has type `&mut T`,
893          * then we treat that like `(&mut *r).inc()`.  This avoids
894          * consuming the original pointer.
895          *
896          * You might think that this would be a natural byproduct of
897          * the auto-deref/auto-ref process.  This is true for `Box<T>`
898          * but not for an `&mut T` receiver.  With `Box<T>`, we would
899          * begin by testing for methods with a self type `Box<T>`,
900          * then autoderef to `T`, then autoref to `&mut T`.  But with
901          * an `&mut T` receiver the process begins with `&mut T`, only
902          * without any autoadjustments.
903          */
904
905         let tcx = self.tcx();
906         return match ty::get(self_ty).sty {
907             ty::ty_rptr(_, self_mt) if default_method_hack(self_mt) => {
908                 (self_ty,
909                  ty::AutoDerefRef {
910                      autoderefs: autoderefs,
911                      autoref: None})
912             }
913             ty::ty_rptr(_, self_mt) => {
914                 let region =
915                     self.infcx().next_region_var(infer::Autoref(self.span));
916                 (ty::mk_rptr(tcx, region, self_mt),
917                  ty::AutoDerefRef {
918                      autoderefs: autoderefs + 1,
919                      autoref: Some(ty::AutoPtr(region, self_mt.mutbl, None))})
920             }
921             _ => {
922                 (self_ty,
923                  ty::AutoDerefRef {
924                      autoderefs: autoderefs,
925                      autoref: None})
926             }
927         };
928
929         fn default_method_hack(self_mt: ty::mt) -> bool {
930             // FIXME(#6129). Default methods can't deal with autoref.
931             //
932             // I am a horrible monster and I pray for death. Currently
933             // the default method code fails when you try to reborrow
934             // because it is not handling types correctly. In lieu of
935             // fixing that, I am introducing this horrible hack. - ndm
936             self_mt.mutbl == MutImmutable && ty::type_is_self(self_mt.ty)
937         }
938     }
939
940     // Takes an [T] - an unwrapped DST pointer (either ~ or &)
941     // [T] to &[T] or &&[T] (note that we started with a &[T] or ~[T] which has
942     // been implicitly derefed).
943     fn auto_slice_vec(&self, ty: ty::t, autoderefs: uint) -> Option<MethodCallee> {
944         let tcx = self.tcx();
945         debug!("auto_slice_vec {}", ppaux::ty_to_string(tcx, ty));
946
947         // First try to borrow to a slice
948         let entry = self.search_for_some_kind_of_autorefd_method(
949             |r, m| AutoPtr(r, m, None), autoderefs, [MutImmutable, MutMutable],
950             |m,r| ty::mk_slice(tcx, r,
951                                ty::mt {ty:ty, mutbl:m}));
952
953         if entry.is_some() {
954             return entry;
955         }
956
957         // Then try to borrow to a slice *and* borrow a pointer.
958         self.search_for_some_kind_of_autorefd_method(
959             |r, m| AutoPtr(r, ast::MutImmutable, Some( box AutoPtr(r, m, None))),
960             autoderefs, [MutImmutable, MutMutable],
961             |m, r| {
962                 let slice_ty = ty::mk_slice(tcx, r,
963                                             ty::mt {ty:ty, mutbl:m});
964                 // NB: we do not try to autoref to a mutable
965                 // pointer. That would be creating a pointer
966                 // to a temporary pointer (the borrowed
967                 // slice), so any update the callee makes to
968                 // it can't be observed.
969                 ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:MutImmutable})
970             })
971     }
972
973     // [T, ..len] -> [T] or &[T] or &&[T]
974     fn auto_unsize_vec(&self, ty: ty::t, autoderefs: uint, len: uint) -> Option<MethodCallee> {
975         let tcx = self.tcx();
976         debug!("auto_unsize_vec {}", ppaux::ty_to_string(tcx, ty));
977
978         // First try to borrow to an unsized vec.
979         let entry = self.search_for_some_kind_of_autorefd_method(
980             |_r, _m| AutoUnsize(ty::UnsizeLength(len)),
981             autoderefs, [MutImmutable, MutMutable],
982             |_m, _r| ty::mk_vec(tcx, ty, None));
983
984         if entry.is_some() {
985             return entry;
986         }
987
988         // Then try to borrow to a slice.
989         let entry = self.search_for_some_kind_of_autorefd_method(
990             |r, m| AutoPtr(r, m, Some(box AutoUnsize(ty::UnsizeLength(len)))),
991             autoderefs, [MutImmutable, MutMutable],
992             |m, r|  ty::mk_slice(tcx, r, ty::mt {ty:ty, mutbl:m}));
993
994         if entry.is_some() {
995             return entry;
996         }
997
998         // Then try to borrow to a slice *and* borrow a pointer.
999         self.search_for_some_kind_of_autorefd_method(
1000             |r, m| AutoPtr(r, m,
1001                            Some(box AutoPtr(r, m,
1002                                             Some(box AutoUnsize(ty::UnsizeLength(len)))))),
1003             autoderefs, [MutImmutable, MutMutable],
1004             |m, r| {
1005                 let slice_ty = ty::mk_slice(tcx, r, ty::mt {ty:ty, mutbl:m});
1006                 ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:MutImmutable})
1007             })
1008     }
1009
1010     fn auto_slice_str(&self, autoderefs: uint) -> Option<MethodCallee> {
1011         let tcx = self.tcx();
1012         debug!("auto_slice_str");
1013
1014         let entry = self.search_for_some_kind_of_autorefd_method(
1015             |r, m| AutoPtr(r, m, None), autoderefs, [MutImmutable],
1016             |_m, r| ty::mk_str_slice(tcx, r, MutImmutable));
1017
1018         if entry.is_some() {
1019             return entry;
1020         }
1021
1022         self.search_for_some_kind_of_autorefd_method(
1023             |r, m| AutoPtr(r, ast::MutImmutable, Some( box AutoPtr(r, m, None))),
1024             autoderefs, [MutImmutable],
1025             |m, r| {
1026                 let slice_ty = ty::mk_str_slice(tcx, r, m);
1027                 ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:m})
1028             })
1029     }
1030
1031     // Coerce Box/&Trait instances to &Trait.
1032     fn auto_slice_trait(&self, ty: ty::t, autoderefs: uint) -> Option<MethodCallee> {
1033         debug!("auto_slice_trait");
1034         match ty::get(ty).sty {
1035             ty_trait(box ty::TyTrait {
1036                     def_id: trt_did,
1037                     substs: ref trt_substs,
1038                     bounds: b,
1039                     .. }) => {
1040                 let tcx = self.tcx();
1041                 self.search_for_some_kind_of_autorefd_method(
1042                     |r, m| AutoPtr(r, m, None),
1043                     autoderefs, [MutImmutable, MutMutable],
1044                     |m, r| {
1045                         let tr = ty::mk_trait(tcx, trt_did, trt_substs.clone(), b);
1046                         ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: m })
1047                     })
1048             }
1049             _ => fail!("Expected ty_trait in auto_slice_trait")
1050         }
1051     }
1052
1053     fn search_for_autofatptrd_method(&self,
1054                                      self_ty: ty::t,
1055                                      autoderefs: uint)
1056                                      -> Option<MethodCallee> {
1057         /*!
1058          * Searches for a candidate by converting things like
1059          * `~[]` to `&[]`.
1060          */
1061
1062         let tcx = self.tcx();
1063         debug!("search_for_autofatptrd_method {}", ppaux::ty_to_string(tcx, self_ty));
1064
1065         let sty = ty::get(self_ty).sty.clone();
1066         match sty {
1067             ty_vec(ty, Some(len)) => self.auto_unsize_vec(ty, autoderefs, len),
1068             ty_vec(ty, None) => self.auto_slice_vec(ty, autoderefs),
1069             ty_str => self.auto_slice_str(autoderefs),
1070             ty_trait(..) => self.auto_slice_trait(self_ty, autoderefs),
1071
1072             ty_closure(..) => {
1073                 // This case should probably be handled similarly to
1074                 // Trait instances.
1075                 None
1076             }
1077
1078             _ => None
1079         }
1080     }
1081
1082     fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
1083                                   -> Option<MethodCallee> {
1084         /*!
1085          *
1086          * Converts any type `T` to `&M T` where `M` is an
1087          * appropriate mutability.
1088          */
1089
1090         let tcx = self.tcx();
1091         match ty::get(self_ty).sty {
1092             ty_bare_fn(..) | ty_box(..) | ty_uniq(..) | ty_rptr(..) |
1093             ty_infer(IntVar(_)) |
1094             ty_infer(FloatVar(_)) |
1095             ty_param(..) | ty_nil | ty_bot | ty_bool |
1096             ty_char | ty_int(..) | ty_uint(..) |
1097             ty_float(..) | ty_enum(..) | ty_ptr(..) | ty_struct(..) |
1098             ty_unboxed_closure(..) | ty_tup(..) | ty_open(..) |
1099             ty_str | ty_vec(..) | ty_trait(..) | ty_closure(..) => {
1100                 self.search_for_some_kind_of_autorefd_method(
1101                     |r, m| AutoPtr(r, m, None), autoderefs, [MutImmutable, MutMutable],
1102                     |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m}))
1103             }
1104
1105             ty_err => None,
1106
1107             ty_infer(TyVar(_)) |
1108             ty_infer(SkolemizedTy(_)) |
1109             ty_infer(SkolemizedIntTy(_)) => {
1110                 self.bug(format!("unexpected type: {}",
1111                                  self.ty_to_string(self_ty)).as_slice());
1112             }
1113         }
1114     }
1115
1116     fn search_for_some_kind_of_autorefd_method(
1117             &self,
1118             kind: |Region, ast::Mutability| -> ty::AutoRef,
1119             autoderefs: uint,
1120             mutbls: &[ast::Mutability],
1121             mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
1122             -> Option<MethodCallee> {
1123         // Hacky. For overloaded derefs, there may be an adjustment
1124         // added to the expression from the outside context, so we do not store
1125         // an explicit adjustment, but rather we hardwire the single deref
1126         // that occurs in trans and mem_categorization.
1127         let self_expr_id = match self.self_expr {
1128             Some(expr) => Some(expr.id),
1129             None => {
1130                 assert_eq!(autoderefs, 0);
1131                 assert!(kind(ty::ReEmpty, ast::MutImmutable) ==
1132                         ty::AutoPtr(ty::ReEmpty, ast::MutImmutable, None));
1133                 None
1134             }
1135         };
1136
1137         // This is hokey. We should have mutability inference as a
1138         // variable.  But for now, try &const, then &, then &mut:
1139         let region =
1140             self.infcx().next_region_var(infer::Autoref(self.span));
1141         for mutbl in mutbls.iter() {
1142             let autoref_ty = mk_autoref_ty(*mutbl, region);
1143             match self.search_for_method(autoref_ty) {
1144                 None => {}
1145                 Some(method) => {
1146                     match self_expr_id {
1147                         Some(self_expr_id) => {
1148                             self.fcx.write_adjustment(
1149                                 self_expr_id,
1150                                 self.span,
1151                                 ty::AdjustDerefRef(ty::AutoDerefRef {
1152                                     autoderefs: autoderefs,
1153                                     autoref: Some(kind(region, *mutbl))
1154                                 }));
1155                         }
1156                         None => {}
1157                     }
1158                     return Some(method);
1159                 }
1160             }
1161         }
1162         None
1163     }
1164
1165     fn search_for_method(&self, rcvr_ty: ty::t) -> Option<MethodCallee> {
1166         debug!("search_for_method(rcvr_ty={})", self.ty_to_string(rcvr_ty));
1167         let _indenter = indenter();
1168
1169         // I am not sure that inherent methods should have higher
1170         // priority, but it is necessary ATM to handle some of the
1171         // existing code.
1172
1173         debug!("searching inherent candidates");
1174         match self.consider_candidates(rcvr_ty, self.inherent_candidates.as_slice()) {
1175             None => {}
1176             Some(mme) => {
1177                 return Some(mme);
1178             }
1179         }
1180
1181         debug!("searching extension candidates");
1182         self.consider_candidates(rcvr_ty, self.extension_candidates.as_slice())
1183     }
1184
1185     fn consider_candidates(&self, rcvr_ty: ty::t,
1186                            candidates: &[Candidate])
1187                            -> Option<MethodCallee> {
1188         let relevant_candidates = self.filter_candidates(rcvr_ty, candidates);
1189
1190         if relevant_candidates.len() == 0 {
1191             return None;
1192         }
1193
1194         if self.report_statics == ReportStaticMethods {
1195             // lookup should only be called with ReportStaticMethods if a regular lookup failed
1196             assert!(relevant_candidates.iter()
1197                                        .all(|c| {
1198                 c.method_ty.explicit_self == ty::StaticExplicitSelfCategory
1199             }));
1200
1201             self.tcx().sess.fileline_note(self.span,
1202                                 "found defined static methods, maybe a `self` is missing?");
1203
1204             for (idx, candidate) in relevant_candidates.iter().enumerate() {
1205                 self.report_candidate(idx, &candidate.origin);
1206             }
1207
1208             // return something so we don't get errors for every mutability
1209             return Some(MethodCallee {
1210                 origin: relevant_candidates.get(0).origin.clone(),
1211                 ty: ty::mk_err(),
1212                 substs: subst::Substs::empty()
1213             });
1214         }
1215
1216         if relevant_candidates.len() > 1 {
1217             span_err!(self.tcx().sess, self.span, E0034,
1218                 "multiple applicable methods in scope");
1219             for (idx, candidate) in relevant_candidates.iter().enumerate() {
1220                 self.report_candidate(idx, &candidate.origin);
1221             }
1222         }
1223
1224         Some(self.confirm_candidate(rcvr_ty, relevant_candidates.get(0)))
1225     }
1226
1227     fn filter_candidates(&self, rcvr_ty: ty::t, candidates: &[Candidate]) -> Vec<Candidate> {
1228         let mut relevant_candidates: Vec<Candidate> = Vec::new();
1229
1230         for candidate_a in candidates.iter().filter(|&c| self.is_relevant(rcvr_ty, c)) {
1231             // Skip this one if we already have one like it
1232             if !relevant_candidates.iter().any(|candidate_b| {
1233                 debug!("attempting to merge {} and {}",
1234                        candidate_a.repr(self.tcx()),
1235                        candidate_b.repr(self.tcx()));
1236                 match (&candidate_a.origin, &candidate_b.origin) {
1237                     (&MethodTypeParam(ref p1), &MethodTypeParam(ref p2)) => {
1238                         let same_trait =
1239                             p1.trait_ref.def_id == p2.trait_ref.def_id;
1240                         let same_method =
1241                             p1.method_num == p2.method_num;
1242                         // it's ok to compare self-ty with `==` here because
1243                         // they are always a TyParam
1244                         let same_param =
1245                             p1.trait_ref.self_ty() == p2.trait_ref.self_ty();
1246                         same_trait && same_method && same_param
1247                     }
1248                     _ => false
1249                 }
1250             }) {
1251                 relevant_candidates.push(candidate_a.clone());
1252             }
1253         }
1254
1255         relevant_candidates
1256     }
1257
1258     fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
1259                          -> MethodCallee
1260     {
1261         // This method performs two sets of substitutions, one after the other:
1262         // 1. Substitute values for any type/lifetime parameters from the impl and
1263         //    method declaration into the method type. This is the function type
1264         //    before it is called; it may still include late bound region variables.
1265         // 2. Instantiate any late bound lifetime parameters in the method itself
1266         //    with fresh region variables.
1267
1268         let tcx = self.tcx();
1269
1270         debug!("confirm_candidate(rcvr_ty={}, candidate={})",
1271                self.ty_to_string(rcvr_ty),
1272                candidate.repr(self.tcx()));
1273
1274         self.enforce_object_limitations(candidate);
1275         self.enforce_drop_trait_limitations(candidate);
1276
1277         // static methods should never have gotten this far:
1278         assert!(candidate.method_ty.explicit_self !=
1279                 ty::StaticExplicitSelfCategory);
1280
1281         // Determine the values for the generic parameters of the method.
1282         // If they were not explicitly supplied, just construct fresh
1283         // variables.
1284         let num_supplied_tps = self.supplied_tps.len();
1285         let num_method_tps = candidate.method_ty.generics.types.len(subst::FnSpace);
1286         let m_types = {
1287             if num_supplied_tps == 0u {
1288                 self.fcx.infcx().next_ty_vars(num_method_tps)
1289             } else if num_method_tps == 0u {
1290                 span_err!(tcx.sess, self.span, E0035,
1291                     "does not take type parameters");
1292                 self.fcx.infcx().next_ty_vars(num_method_tps)
1293             } else if num_supplied_tps != num_method_tps {
1294                 span_err!(tcx.sess, self.span, E0036,
1295                     "incorrect number of type parameters given for this method");
1296                 self.fcx.infcx().next_ty_vars(num_method_tps)
1297             } else {
1298                 Vec::from_slice(self.supplied_tps)
1299             }
1300         };
1301
1302         // Create subst for early-bound lifetime parameters, combining
1303         // parameters from the type and those from the method.
1304         //
1305         // FIXME -- permit users to manually specify lifetimes
1306         let m_regions =
1307             self.fcx.infcx().region_vars_for_defs(
1308                 self.span,
1309                 candidate.method_ty.generics.regions.get_slice(subst::FnSpace));
1310
1311         let all_substs = candidate.rcvr_substs.clone().with_method(m_types, m_regions);
1312
1313         let ref bare_fn_ty = candidate.method_ty.fty;
1314
1315         // Compute the method type with type parameters substituted
1316         debug!("fty={} all_substs={}",
1317                bare_fn_ty.repr(tcx),
1318                all_substs.repr(tcx));
1319
1320         let fn_sig = &bare_fn_ty.sig;
1321         let inputs = match candidate.origin {
1322             MethodTraitObject(..) => {
1323                 // For annoying reasons, we've already handled the
1324                 // substitution of self for object calls.
1325                 let args = fn_sig.inputs.slice_from(1).iter().map(|t| {
1326                     t.subst(tcx, &all_substs)
1327                 });
1328                 Some(*fn_sig.inputs.get(0)).into_iter().chain(args).collect()
1329             }
1330             _ => fn_sig.inputs.subst(tcx, &all_substs)
1331         };
1332         let fn_sig = ty::FnSig {
1333             binder_id: fn_sig.binder_id,
1334             inputs: inputs,
1335             output: fn_sig.output.subst(tcx, &all_substs),
1336             variadic: fn_sig.variadic
1337         };
1338
1339         debug!("after subst, fty={}", fn_sig.repr(tcx));
1340
1341         // Replace any bound regions that appear in the function
1342         // signature with region variables
1343         let (_, fn_sig) = replace_late_bound_regions_in_fn_sig(
1344             tcx, &fn_sig,
1345             |br| self.fcx.infcx().next_region_var(
1346                 infer::LateBoundRegion(self.span, br)));
1347         let transformed_self_ty = *fn_sig.inputs.get(0);
1348         let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
1349             sig: fn_sig,
1350             fn_style: bare_fn_ty.fn_style,
1351             abi: bare_fn_ty.abi.clone(),
1352         });
1353         debug!("after replacing bound regions, fty={}", self.ty_to_string(fty));
1354
1355         // Before, we only checked whether self_ty could be a subtype
1356         // of rcvr_ty; now we actually make it so (this may cause
1357         // variables to unify etc).  Since we checked beforehand, and
1358         // nothing has changed in the meantime, this unification
1359         // should never fail.
1360         let span = self.self_expr.map_or(self.span, |e| e.span);
1361         match self.fcx.mk_subty(false, infer::Misc(span),
1362                                 rcvr_ty, transformed_self_ty) {
1363             Ok(_) => {}
1364             Err(_) => {
1365                 self.bug(format!(
1366                         "{} was a subtype of {} but now is not?",
1367                         self.ty_to_string(rcvr_ty),
1368                         self.ty_to_string(transformed_self_ty)).as_slice());
1369             }
1370         }
1371
1372         self.fcx.add_obligations_for_parameters(
1373             traits::ObligationCause::misc(self.span),
1374             &all_substs,
1375             &candidate.method_ty.generics);
1376
1377         MethodCallee {
1378             origin: candidate.origin.clone(),
1379             ty: fty,
1380             substs: all_substs
1381         }
1382     }
1383
1384     fn enforce_object_limitations(&self, candidate: &Candidate) {
1385         /*!
1386          * There are some limitations to calling functions through an
1387          * object, because (a) the self type is not known
1388          * (that's the whole point of a trait instance, after all, to
1389          * obscure the self type) and (b) the call must go through a
1390          * vtable and hence cannot be monomorphized.
1391          */
1392
1393         match candidate.origin {
1394             MethodStatic(..) |
1395             MethodTypeParam(..) |
1396             MethodStaticUnboxedClosure(..) => {
1397                 return; // not a call to a trait instance
1398             }
1399             MethodTraitObject(..) => {}
1400         }
1401
1402         match candidate.method_ty.explicit_self {
1403             ty::StaticExplicitSelfCategory => { // reason (a) above
1404                 self.tcx().sess.span_err(
1405                     self.span,
1406                     "cannot call a method without a receiver \
1407                      through an object");
1408             }
1409
1410             ty::ByValueExplicitSelfCategory |
1411             ty::ByReferenceExplicitSelfCategory(..) |
1412             ty::ByBoxExplicitSelfCategory => {}
1413         }
1414
1415         // reason (a) above
1416         let check_for_self_ty = |ty| {
1417             if ty::type_has_self(ty) {
1418                 span_err!(self.tcx().sess, self.span, E0038,
1419                     "cannot call a method whose type contains a \
1420                      self-type through an object");
1421                 true
1422             } else {
1423                 false
1424             }
1425         };
1426         let ref sig = candidate.method_ty.fty.sig;
1427         let mut found_self_ty = false;
1428         for &input_ty in sig.inputs.iter() {
1429             if check_for_self_ty(input_ty) {
1430                 found_self_ty = true;
1431                 break;
1432             }
1433         }
1434         if !found_self_ty {
1435             check_for_self_ty(sig.output);
1436         }
1437
1438         if candidate.method_ty.generics.has_type_params(subst::FnSpace) {
1439             // reason (b) above
1440             span_err!(self.tcx().sess, self.span, E0039,
1441                 "cannot call a generic method through an object");
1442         }
1443     }
1444
1445     fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
1446         // No code can call the finalize method explicitly.
1447         let bad;
1448         match candidate.origin {
1449             MethodStatic(method_id) => {
1450                 bad = self.tcx().destructors.borrow().contains(&method_id);
1451             }
1452             MethodStaticUnboxedClosure(_) => bad = false,
1453             // FIXME: does this properly enforce this on everything now
1454             // that self has been merged in? -sully
1455             MethodTypeParam(MethodParam { trait_ref: ref trait_ref, .. }) |
1456             MethodTraitObject(MethodObject { trait_ref: ref trait_ref, .. }) => {
1457                 bad = self.tcx().destructor_for_type.borrow()
1458                           .contains_key(&trait_ref.def_id);
1459             }
1460         }
1461
1462         if bad {
1463             span_err!(self.tcx().sess, self.span, E0040,
1464                 "explicit call to destructor");
1465         }
1466     }
1467
1468     // `rcvr_ty` is the type of the expression. It may be a subtype of a
1469     // candidate method's `self_ty`.
1470     fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
1471         debug!("is_relevant(rcvr_ty={}, candidate={})",
1472                self.ty_to_string(rcvr_ty), candidate.repr(self.tcx()));
1473
1474         return match candidate.method_ty.explicit_self {
1475             StaticExplicitSelfCategory => {
1476                 debug!("(is relevant?) explicit self is static");
1477                 self.report_statics == ReportStaticMethods
1478             }
1479
1480             ByValueExplicitSelfCategory => {
1481                 debug!("(is relevant?) explicit self is by-value");
1482                 match ty::get(rcvr_ty).sty {
1483                     ty::ty_uniq(typ) => {
1484                         match ty::get(typ).sty {
1485                             ty::ty_trait(box ty::TyTrait {
1486                                 def_id: self_did,
1487                                 ..
1488                             }) => {
1489                                 rcvr_matches_object(self_did, candidate) ||
1490                                     rcvr_matches_ty(self.fcx,
1491                                                     rcvr_ty,
1492                                                     candidate)
1493                             }
1494                             _ => {
1495                                 rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
1496                             }
1497                         }
1498                     }
1499                     _ => rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
1500                 }
1501             }
1502
1503             ByReferenceExplicitSelfCategory(_, m) => {
1504                 debug!("(is relevant?) explicit self is a region");
1505                 match ty::get(rcvr_ty).sty {
1506                     ty::ty_rptr(_, mt) => {
1507                         match ty::get(mt.ty).sty {
1508                             ty::ty_trait(box ty::TyTrait { def_id: self_did, .. }) => {
1509                                 mutability_matches(mt.mutbl, m) &&
1510                                 rcvr_matches_object(self_did, candidate)
1511                             }
1512                             _ => mutability_matches(mt.mutbl, m) &&
1513                                  rcvr_matches_ty(self.fcx, mt.ty, candidate)
1514                         }
1515                     }
1516
1517                     _ => false
1518                 }
1519             }
1520
1521             ByBoxExplicitSelfCategory => {
1522                 debug!("(is relevant?) explicit self is a unique pointer");
1523                 match ty::get(rcvr_ty).sty {
1524                     ty::ty_uniq(typ) => {
1525                         match ty::get(typ).sty {
1526                             ty::ty_trait(box ty::TyTrait { def_id: self_did, .. }) => {
1527                                 rcvr_matches_object(self_did, candidate)
1528                             }
1529                             _ => rcvr_matches_ty(self.fcx, typ, candidate),
1530                         }
1531                     }
1532
1533                     _ => false
1534                 }
1535             }
1536         };
1537
1538         fn rcvr_matches_object(self_did: ast::DefId,
1539                                candidate: &Candidate) -> bool {
1540             match candidate.rcvr_match_condition {
1541                 RcvrMatchesIfObject(desired_did) => {
1542                     self_did == desired_did
1543                 }
1544                 RcvrMatchesIfSubtype(_) | RcvrMatchesIfEqtype(_) => {
1545                     false
1546                 }
1547             }
1548         }
1549
1550         fn rcvr_matches_ty(fcx: &FnCtxt,
1551                            rcvr_ty: ty::t,
1552                            candidate: &Candidate) -> bool {
1553             match candidate.rcvr_match_condition {
1554                 RcvrMatchesIfObject(_) => {
1555                     false
1556                 }
1557                 RcvrMatchesIfSubtype(of_type) => {
1558                     fcx.can_mk_subty(rcvr_ty, of_type).is_ok()
1559                 }
1560                 RcvrMatchesIfEqtype(of_type) => {
1561                     fcx.can_mk_eqty(rcvr_ty, of_type).is_ok()
1562                 }
1563             }
1564         }
1565
1566         fn mutability_matches(self_mutbl: ast::Mutability,
1567                               candidate_mutbl: ast::Mutability)
1568                               -> bool {
1569             //! True if `self_mutbl <: candidate_mutbl`
1570             self_mutbl == candidate_mutbl
1571         }
1572     }
1573
1574     fn report_candidate(&self, idx: uint, origin: &MethodOrigin) {
1575         match *origin {
1576             MethodStatic(impl_did) => {
1577                 let did = if self.report_statics == ReportStaticMethods {
1578                     // If we're reporting statics, we want to report the trait
1579                     // definition if possible, rather than an impl
1580                     match ty::trait_item_of_item(self.tcx(), impl_did) {
1581                         None | Some(TypeTraitItemId(_)) => {
1582                             debug!("(report candidate) No trait method \
1583                                     found");
1584                             impl_did
1585                         }
1586                         Some(MethodTraitItemId(trait_did)) => {
1587                             debug!("(report candidate) Found trait ref");
1588                             trait_did
1589                         }
1590                     }
1591                 } else {
1592                     // If it is an instantiated default method, use the original
1593                     // default method for error reporting.
1594                     match provided_source(self.tcx(), impl_did) {
1595                         None => impl_did,
1596                         Some(did) => did
1597                     }
1598                 };
1599                 self.report_static_candidate(idx, did)
1600             }
1601             MethodStaticUnboxedClosure(did) => {
1602                 self.report_static_candidate(idx, did)
1603             }
1604             MethodTypeParam(ref mp) => {
1605                 self.report_param_candidate(idx, mp.trait_ref.def_id)
1606             }
1607             MethodTraitObject(ref mo) => {
1608                 self.report_trait_candidate(idx, mo.trait_ref.def_id)
1609             }
1610         }
1611     }
1612
1613     fn report_static_candidate(&self, idx: uint, did: DefId) {
1614         let span = if did.krate == ast::LOCAL_CRATE {
1615             self.tcx().map.span(did.node)
1616         } else {
1617             self.span
1618         };
1619         span_note!(self.tcx().sess, span,
1620             "candidate #{} is `{}`",
1621             idx + 1u, ty::item_path_str(self.tcx(), did));
1622     }
1623
1624     fn report_param_candidate(&self, idx: uint, did: DefId) {
1625         span_note!(self.tcx().sess, self.span,
1626             "candidate #{} derives from the bound `{}`",
1627             idx + 1u, ty::item_path_str(self.tcx(), did));
1628     }
1629
1630     fn report_trait_candidate(&self, idx: uint, did: DefId) {
1631         span_note!(self.tcx().sess, self.span,
1632             "candidate #{} derives from the type of the receiver, \
1633             which is the trait `{}`",
1634             idx + 1u, ty::item_path_str(self.tcx(), did));
1635     }
1636
1637     fn infcx(&'a self) -> &'a infer::InferCtxt<'a, 'tcx> {
1638         &self.fcx.inh.infcx
1639     }
1640
1641     fn tcx(&self) -> &'a ty::ctxt<'tcx> {
1642         self.fcx.tcx()
1643     }
1644
1645     fn ty_to_string(&self, t: ty::t) -> String {
1646         self.fcx.infcx().ty_to_string(t)
1647     }
1648
1649     fn did_to_string(&self, did: DefId) -> String {
1650         ty::item_path_str(self.tcx(), did)
1651     }
1652
1653     fn bug(&self, s: &str) -> ! {
1654         self.tcx().sess.span_bug(self.span, s)
1655     }
1656 }
1657
1658 impl Repr for Candidate {
1659     fn repr(&self, tcx: &ty::ctxt) -> String {
1660         format!("Candidate(rcvr_ty={}, rcvr_substs={}, method_ty={}, \
1661                  origin={:?})",
1662                 self.rcvr_match_condition.repr(tcx),
1663                 self.rcvr_substs.repr(tcx),
1664                 self.method_ty.repr(tcx),
1665                 self.origin)
1666     }
1667 }
1668
1669 impl Repr for RcvrMatchCondition {
1670     fn repr(&self, tcx: &ty::ctxt) -> String {
1671         match *self {
1672             RcvrMatchesIfObject(d) => {
1673                 format!("RcvrMatchesIfObject({})", d.repr(tcx))
1674             }
1675             RcvrMatchesIfSubtype(t) => {
1676                 format!("RcvrMatchesIfSubtype({})", t.repr(tcx))
1677             }
1678             RcvrMatchesIfEqtype(t) => {
1679                 format!("RcvrMatchesIfEqtype({})", t.repr(tcx))
1680             }
1681         }
1682     }
1683 }