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.
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.
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
20 ## Candidate collection
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).
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
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.
45 For better or worse, we currently give weight to inherent methods over
46 extension methods during candidate selection (below).
48 ## Candidate selection
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.
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
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.
84 use middle::subst::Subst;
87 use middle::typeck::astconv::AstConv;
88 use middle::typeck::check::{FnCtxt, PreferMutLvalue, impl_self_ty};
89 use middle::typeck::check;
90 use middle::typeck::infer;
91 use middle::typeck::MethodCallee;
92 use middle::typeck::{MethodOrigin, MethodParam};
93 use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure, MethodObject};
94 use middle::typeck::{param_index};
95 use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
96 use middle::typeck::TypeAndSubsts;
97 use util::common::indenter;
99 use util::ppaux::Repr;
101 use std::collections::HashSet;
103 use syntax::ast::{DefId, MutImmutable, MutMutable};
105 use syntax::codemap::Span;
106 use syntax::parse::token;
108 #[deriving(PartialEq)]
109 pub enum CheckTraitsFlag {
111 CheckTraitsAndInherentMethods,
114 #[deriving(PartialEq)]
115 pub enum AutoderefReceiverFlag {
117 DontAutoderefReceiver,
120 #[deriving(PartialEq)]
121 pub enum StaticMethodsFlag {
126 pub fn lookup<'a, 'tcx>(
127 fcx: &'a FnCtxt<'a, 'tcx>,
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 {
143 self_expr: Some(self_expr),
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,
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()));
159 debug!("searching inherent candidates");
160 lcx.push_inherent_candidates(self_ty);
161 let mme = lcx.search(self_ty);
166 debug!("searching extension candidates");
167 lcx.reset_candidates();
168 lcx.push_bound_candidates(self_ty, None);
169 lcx.push_extension_candidates(expr.id);
173 pub fn lookup_in_trait<'a, 'tcx>(
174 fcx: &'a FnCtxt<'a, 'tcx>,
176 // In a call `a.b::<X, Y, ...>(...)`:
177 span: Span, // The expression `a.b(...)`'s span.
178 self_expr: Option<&'a ast::Expr>, // The expression `a`, if available.
179 m_name: ast::Name, // The name `b`.
180 trait_did: DefId, // The trait to limit the lookup to.
181 self_ty: ty::t, // The type of `a`.
182 supplied_tps: &'a [ty::t], // The list of types X, Y, ... .
183 autoderef_receiver: AutoderefReceiverFlag,
184 report_statics: StaticMethodsFlag)
185 -> Option<MethodCallee> {
186 let mut lcx = LookupContext {
189 self_expr: self_expr,
191 supplied_tps: supplied_tps,
192 impl_dups: HashSet::new(),
193 inherent_candidates: Vec::new(),
194 extension_candidates: Vec::new(),
195 deref_args: check::DoDerefArgs,
196 check_traits: CheckTraitsOnly,
197 autoderef_receiver: autoderef_receiver,
198 report_statics: report_statics,
201 debug!("method lookup_in_trait(self_ty={}, self_expr={})",
202 self_ty.repr(fcx.tcx()), self_expr.map(|e| e.repr(fcx.tcx())));
204 lcx.push_bound_candidates(self_ty, Some(trait_did));
205 lcx.push_extension_candidate(trait_did);
209 // Determine the index of a method in the list of all methods belonging
210 // to a trait and its supertraits.
211 fn get_method_index(tcx: &ty::ctxt,
212 trait_ref: &TraitRef,
213 subtrait: Rc<TraitRef>,
214 n_method: uint) -> uint {
215 // We need to figure the "real index" of the method in a
216 // listing of all the methods of an object. We do this by
217 // iterating down the supertraits of the object's trait until
218 // we find the trait the method came from, counting up the
219 // methods from them.
220 let mut method_count = 0;
221 ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
222 if bound_ref.def_id == trait_ref.def_id {
225 let trait_items = ty::trait_items(tcx, bound_ref.def_id);
226 for trait_item in trait_items.iter() {
228 ty::MethodTraitItem(_) => method_count += 1,
234 method_count + n_method
237 fn construct_transformed_self_ty_for_object(
240 trait_def_id: ast::DefId,
241 rcvr_substs: &subst::Substs,
242 rcvr_bounds: ty::ExistentialBounds,
243 method_ty: &ty::Method)
247 * This is a bit tricky. We have a match against a trait method
248 * being invoked on an object, and we want to generate the
249 * self-type. As an example, consider a trait
252 * fn r_method<'a>(&'a self);
253 * fn u_method(Box<self>);
256 * Now, assuming that `r_method` is being called, we want the
257 * result to be `&'a Foo`. Assuming that `u_method` is being
258 * called, we want the result to be `Box<Foo>`. Of course,
259 * this transformation has already been done as part of
260 * `method_ty.fty.sig.inputs[0]`, but there the type
261 * is expressed in terms of `Self` (i.e., `&'a Self`, `Box<Self>`).
262 * Because objects are not standalone types, we can't just substitute
263 * `s/Self/Foo/`, so we must instead perform this kind of hokey
267 let mut obj_substs = rcvr_substs.clone();
269 // The subst we get in has Err as the "Self" type. For an object
270 // type, we don't put any type into the Self paramspace, so let's
271 // make a copy of rcvr_substs that has the Self paramspace empty.
272 obj_substs.types.pop(subst::SelfSpace).unwrap();
274 match method_ty.explicit_self {
275 StaticExplicitSelfCategory => {
276 tcx.sess.span_bug(span, "static method for object type receiver");
278 ByValueExplicitSelfCategory => {
279 let tr = ty::mk_trait(tcx, trait_def_id, obj_substs, rcvr_bounds);
282 ByReferenceExplicitSelfCategory(..) | ByBoxExplicitSelfCategory => {
283 let transformed_self_ty = *method_ty.fty.sig.inputs.get(0);
284 match ty::get(transformed_self_ty).sty {
285 ty::ty_rptr(r, mt) => { // must be SelfRegion
286 let r = r.subst(tcx, rcvr_substs); // handle Early-Bound lifetime
287 let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
289 ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: mt.mutbl })
291 ty::ty_uniq(_) => { // must be SelfUniq
292 let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
297 tcx.sess.span_bug(span,
298 format!("'impossible' transformed_self_ty: {}",
299 transformed_self_ty.repr(tcx)).as_slice());
306 struct LookupContext<'a, 'tcx: 'a> {
307 fcx: &'a FnCtxt<'a, 'tcx>,
310 // The receiver to the method call. Only `None` in the case of
311 // an overloaded autoderef, where the receiver may be an intermediate
312 // state like "the expression `x` when it has been autoderef'd
314 self_expr: Option<&'a ast::Expr>,
317 supplied_tps: &'a [ty::t],
318 impl_dups: HashSet<DefId>,
319 inherent_candidates: Vec<Candidate>,
320 extension_candidates: Vec<Candidate>,
321 deref_args: check::DerefArgs,
322 check_traits: CheckTraitsFlag,
323 autoderef_receiver: AutoderefReceiverFlag,
324 report_statics: StaticMethodsFlag,
328 * A potential method that might be called, assuming the receiver
329 * is of a suitable type.
333 rcvr_match_condition: RcvrMatchCondition,
334 rcvr_substs: subst::Substs,
335 method_ty: Rc<ty::Method>,
336 origin: MethodOrigin,
339 /// This type represents the conditions under which the receiver is
340 /// considered to "match" a given method candidate. Typically the test
341 /// is whether the receiver is of a particular type. However, this
342 /// type is the type of the receiver *after accounting for the
343 /// method's self type* (e.g., if the method is an `Box<self>` method, we
344 /// have *already verified* that the receiver is of some type `Box<T>` and
345 /// now we must check that the type `T` is correct). Unfortunately,
346 /// because traits are not types, this is a pain to do.
348 pub enum RcvrMatchCondition {
349 RcvrMatchesIfObject(ast::DefId),
350 RcvrMatchesIfSubtype(ty::t),
351 RcvrMatchesIfEqtype(ty::t)
354 impl<'a, 'tcx> LookupContext<'a, 'tcx> {
355 fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {
356 let span = self.self_expr.map_or(self.span, |e| e.span);
357 let self_expr_id = self.self_expr.map(|e| e.id);
361 self.fcx, span, self_ty, self_expr_id, PreferMutLvalue,
362 |self_ty, autoderefs| self.search_step(self_ty, autoderefs));
365 Some(Some(result)) => Some(result),
370 fn search_step(&self,
373 -> Option<Option<MethodCallee>> {
374 debug!("search_step: self_ty={} autoderefs={}",
375 self.ty_to_string(self_ty), autoderefs);
377 match self.deref_args {
378 check::DontDerefArgs => {
379 match self.search_for_autoderefd_method(self_ty, autoderefs) {
380 Some(result) => return Some(Some(result)),
384 match self.search_for_autoptrd_method(self_ty, autoderefs) {
385 Some(result) => return Some(Some(result)),
389 check::DoDerefArgs => {
390 match self.search_for_autoptrd_method(self_ty, autoderefs) {
391 Some(result) => return Some(Some(result)),
395 match self.search_for_autoderefd_method(self_ty, autoderefs) {
396 Some(result) => return Some(Some(result)),
402 // If we are searching for an overloaded deref, no
403 // need to try coercing a `~[T]` to an `&[T]` and
404 // searching for an overloaded deref on *that*.
405 if !self.is_overloaded_deref() {
406 match self.search_for_autofatptrd_method(self_ty, autoderefs) {
407 Some(result) => return Some(Some(result)),
412 // Don't autoderef if we aren't supposed to.
413 if self.autoderef_receiver == DontAutoderefReceiver {
420 fn is_overloaded_deref(&self) -> bool {
421 self.self_expr.is_none()
424 // ______________________________________________________________________
425 // Candidate collection (see comment at start of file)
427 fn reset_candidates(&mut self) {
428 self.inherent_candidates = Vec::new();
429 self.extension_candidates = Vec::new();
432 fn push_inherent_candidates(&mut self, self_ty: ty::t) {
434 * Collect all inherent candidates into
435 * `self.inherent_candidates`. See comment at the start of
436 * the file. To find the inherent candidates, we repeatedly
437 * deref the self-ty to find the "base-type". So, for
438 * example, if the receiver is Box<Box<C>> where `C` is a struct type,
439 * we'll want to find the inherent impls for `C`.
442 let span = self.self_expr.map_or(self.span, |e| e.span);
443 check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
444 match get(self_ty).sty {
445 ty_trait(box TyTrait { def_id, ref substs, bounds, .. }) => {
446 self.push_inherent_candidates_from_object(
447 def_id, substs, bounds);
448 self.push_inherent_impl_candidates_for_type(def_id);
452 ty_unboxed_closure(did, _) => {
453 if self.check_traits == CheckTraitsAndInherentMethods {
454 self.push_inherent_impl_candidates_for_type(did);
457 _ => { /* No inherent methods in these types */ }
460 // Don't autoderef if we aren't supposed to.
461 if self.autoderef_receiver == DontAutoderefReceiver {
469 fn push_bound_candidates(&mut self, self_ty: ty::t, restrict_to: Option<DefId>) {
470 let span = self.self_expr.map_or(self.span, |e| e.span);
471 check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
472 match get(self_ty).sty {
474 self.push_inherent_candidates_from_param(self_ty, restrict_to, p);
476 ty_unboxed_closure(closure_did, _) => {
477 self.push_unboxed_closure_call_candidates_if_applicable(
480 _ => { /* No bound methods in these types */ }
483 // Don't autoderef if we aren't supposed to.
484 if self.autoderef_receiver == DontAutoderefReceiver {
492 fn push_extension_candidate(&mut self, trait_did: DefId) {
493 ty::populate_implementations_for_trait_if_necessary(self.tcx(), trait_did);
495 // Look for explicit implementations.
496 let impl_items = self.tcx().impl_items.borrow();
497 for impl_infos in self.tcx().trait_impls.borrow().find(&trait_did).iter() {
498 for impl_did in impl_infos.borrow().iter() {
499 let items = impl_items.get(impl_did);
500 self.push_candidates_from_impl(*impl_did,
507 fn push_extension_candidates(&mut self, expr_id: ast::NodeId) {
508 // If the method being called is associated with a trait, then
509 // find all the impls of that trait. Each of those are
511 let opt_applicable_traits = self.fcx.ccx.trait_map.find(&expr_id);
512 for applicable_traits in opt_applicable_traits.move_iter() {
513 for trait_did in applicable_traits.iter() {
514 debug!("push_extension_candidates() found trait: {}",
515 if trait_did.krate == ast::LOCAL_CRATE {
516 self.fcx.ccx.tcx.map.node_to_string(trait_did.node)
518 "(external)".to_string()
520 self.push_extension_candidate(*trait_did);
525 fn push_unboxed_closure_call_candidate_if_applicable(
529 closure_function_type: &ClosureTy) {
530 let trait_item = ty::trait_items(self.tcx(), trait_did).get(0)
532 let method = match trait_item {
533 ty::MethodTraitItem(method) => method,
536 // Make sure it has the right name!
537 if method.ident.name != self.m_name {
541 let vcx = self.fcx.vtable_context();
543 // Get the tupled type of the arguments.
544 let arguments_type = *closure_function_type.sig.inputs.get(0);
545 let return_type = closure_function_type.sig.output;
548 vcx.infcx.next_region_var(infer::MiscVariable(self.span));
549 let unboxed_closure_type = ty::mk_unboxed_closure(self.tcx(),
552 self.extension_candidates.push(Candidate {
553 rcvr_match_condition:
554 RcvrMatchesIfSubtype(unboxed_closure_type),
555 rcvr_substs: subst::Substs::new_trait(
556 vec![arguments_type, return_type],
558 *vcx.infcx.next_ty_vars(1).get(0)),
560 origin: MethodStaticUnboxedClosure(closure_did),
564 fn push_unboxed_closure_call_candidates_if_applicable(
566 closure_did: DefId) {
567 match self.tcx().unboxed_closures.borrow().find(&closure_did) {
568 None => {} // Fall through to try inherited.
570 let tcx = self.tcx();
571 self.push_unboxed_closure_call_candidate_if_applicable(
572 closure.kind.trait_did(tcx),
574 &closure.closure_type);
579 match self.fcx.inh.unboxed_closures.borrow().find(&closure_did) {
581 let tcx = self.tcx();
582 self.push_unboxed_closure_call_candidate_if_applicable(
583 closure.kind.trait_did(tcx),
585 &closure.closure_type);
591 self.tcx().sess.bug("didn't find unboxed closure type in tcx map or \
592 inherited map, so there")
595 fn push_inherent_candidates_from_object(&mut self,
597 substs: &subst::Substs,
598 bounds: ty::ExistentialBounds) {
599 debug!("push_inherent_candidates_from_object(did={}, substs={})",
600 self.did_to_string(did),
601 substs.repr(self.tcx()));
602 let tcx = self.tcx();
603 let span = self.span;
605 // It is illegal to invoke a method on a trait instance that
606 // refers to the `self` type. An error will be reported by
607 // `enforce_object_limitations()` if the method refers
608 // to the `Self` type. Substituting ty_err here allows
609 // compiler to soldier on.
611 // `confirm_candidate()` also relies upon this substitution
613 let rcvr_substs = substs.with_self_ty(ty::mk_err());
614 let trait_ref = Rc::new(TraitRef {
616 substs: rcvr_substs.clone()
619 self.push_inherent_candidates_from_bounds_inner(
620 &[trait_ref.clone()],
621 |_this, new_trait_ref, m, method_num, _bound_num| {
623 get_method_index(tcx, &*new_trait_ref,
624 trait_ref.clone(), method_num);
625 let mut m = (*m).clone();
626 // We need to fix up the transformed self type.
627 *m.fty.sig.inputs.get_mut(0) =
628 construct_transformed_self_ty_for_object(
629 tcx, span, did, &rcvr_substs, bounds, &m);
632 rcvr_match_condition: RcvrMatchesIfObject(did),
633 rcvr_substs: new_trait_ref.substs.clone(),
634 method_ty: Rc::new(m),
635 origin: MethodObject(MethodObject {
636 trait_id: new_trait_ref.def_id,
637 object_trait_id: did,
638 method_num: method_num,
639 real_index: vtable_index
645 fn push_inherent_candidates_from_param(&mut self,
647 restrict_to: Option<DefId>,
649 debug!("push_inherent_candidates_from_param(param_ty={:?})",
651 self.push_inherent_candidates_from_bounds(
656 param_index { space: param_ty.space, index: param_ty.idx });
660 fn push_inherent_candidates_from_bounds(&mut self,
662 space: subst::ParamSpace,
664 restrict_to: Option<DefId>,
665 param: param_index) {
667 self.fcx.inh.param_env.bounds.get(space, index).trait_bounds
669 self.push_inherent_candidates_from_bounds_inner(bounds,
670 |this, trait_ref, m, method_num, bound_num| {
673 if trait_did != trait_ref.def_id {
680 let condition = match m.explicit_self {
681 ByReferenceExplicitSelfCategory(_, mt) if mt == MutMutable =>
682 RcvrMatchesIfEqtype(self_ty),
684 RcvrMatchesIfSubtype(self_ty)
687 debug!("found match: trait_ref={} substs={} m={}",
688 trait_ref.repr(this.tcx()),
689 trait_ref.substs.repr(this.tcx()),
691 assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
692 trait_ref.substs.types.get_slice(subst::TypeSpace).len());
693 assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
694 trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
695 assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
696 trait_ref.substs.types.get_slice(subst::SelfSpace).len());
697 assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
698 trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
700 rcvr_match_condition: condition,
701 rcvr_substs: trait_ref.substs.clone(),
703 origin: MethodParam(MethodParam {
704 trait_id: trait_ref.def_id,
705 method_num: method_num,
707 bound_num: bound_num,
713 // Do a search through a list of bounds, using a callback to actually
714 // create the candidates.
715 fn push_inherent_candidates_from_bounds_inner(
717 bounds: &[Rc<TraitRef>],
718 mk_cand: |this: &mut LookupContext,
723 -> Option<Candidate>) {
724 let tcx = self.tcx();
725 let mut next_bound_idx = 0; // count only trait bounds
727 ty::each_bound_trait_and_supertraits(tcx, bounds, |bound_trait_ref| {
728 let this_bound_idx = next_bound_idx;
731 let trait_items = ty::trait_items(tcx, bound_trait_ref.def_id);
732 match trait_items.iter().position(|ti| {
734 ty::MethodTraitItem(ref m) => {
735 m.explicit_self != ty::StaticExplicitSelfCategory &&
736 m.ident.name == self.m_name
741 let method = match *trait_items.get(pos) {
742 ty::MethodTraitItem(ref method) => (*method).clone(),
751 debug!("pushing inherent candidate for param: {}",
752 cand.repr(self.tcx()));
753 self.inherent_candidates.push(cand);
759 debug!("trait doesn't contain method: {:?}",
760 bound_trait_ref.def_id);
761 // check next trait or bound
769 fn push_inherent_impl_candidates_for_type(&mut self, did: DefId) {
770 // Read the inherent implementation candidates for this type from the
771 // metadata if necessary.
772 ty::populate_implementations_for_type_if_necessary(self.tcx(), did);
774 let impl_items = self.tcx().impl_items.borrow();
775 for impl_infos in self.tcx().inherent_impls.borrow().find(&did).iter() {
776 for impl_did in impl_infos.borrow().iter() {
777 let items = impl_items.get(impl_did);
778 self.push_candidates_from_impl(*impl_did,
785 fn push_candidates_from_impl(&mut self,
787 impl_items: &[ImplOrTraitItemId],
788 is_extension: bool) {
789 let did = if self.report_statics == ReportStaticMethods {
790 // we only want to report each base trait once
791 match ty::impl_trait_ref(self.tcx(), impl_did) {
792 Some(trait_ref) => trait_ref.def_id,
799 if !self.impl_dups.insert(did) {
800 return; // already visited
803 debug!("push_candidates_from_impl: {} {}",
804 token::get_name(self.m_name),
807 ty::impl_or_trait_item(self.tcx(),
808 did.def_id()).ident()
810 .collect::<Vec<ast::Ident>>()
813 let method = match impl_items.iter()
815 ty::impl_or_trait_item(self.tcx(),
819 m.ident().name == self.m_name
821 Some(ty::MethodTraitItem(method)) => method,
822 None => { return; } // No method with the right name.
825 // determine the `self` of the impl with fresh
826 // variables for each parameter:
827 let span = self.self_expr.map_or(self.span, |e| e.span);
828 let vcx = self.fcx.vtable_context();
832 } = impl_self_ty(&vcx, span, impl_did);
834 let condition = match method.explicit_self {
835 ByReferenceExplicitSelfCategory(_, mt) if mt == MutMutable =>
836 RcvrMatchesIfEqtype(impl_ty),
838 RcvrMatchesIfSubtype(impl_ty)
841 let candidates = if is_extension {
842 &mut self.extension_candidates
844 &mut self.inherent_candidates
847 candidates.push(Candidate {
848 rcvr_match_condition: condition,
849 rcvr_substs: impl_substs,
850 origin: MethodStatic(method.def_id),
855 // ______________________________________________________________________
856 // Candidate selection (see comment at start of file)
858 fn search_for_autoderefd_method(&self,
861 -> Option<MethodCallee> {
862 // Hacky. For overloaded derefs, there may be an adjustment
863 // added to the expression from the outside context, so we do not store
864 // an explicit adjustment, but rather we hardwire the single deref
865 // that occurs in trans and mem_categorization.
866 if self.self_expr.is_none() {
870 let (self_ty, auto_deref_ref) = self.consider_reborrow(self_ty, autoderefs);
871 let adjustment = Some((self.self_expr.unwrap().id, ty::AutoDerefRef(auto_deref_ref)));
873 match self.search_for_method(self_ty) {
876 debug!("(searching for autoderef'd method) writing \
877 adjustment {:?} for {}", adjustment, self.ty_to_string(self_ty));
879 Some((self_expr_id, adj)) => {
880 self.fcx.write_adjustment(self_expr_id, adj);
889 fn consider_reborrow(&self,
892 -> (ty::t, ty::AutoDerefRef) {
894 * In the event that we are invoking a method with a receiver
895 * of a borrowed type like `&T`, `&mut T`, or `&mut [T]`,
896 * we will "reborrow" the receiver implicitly. For example, if
897 * you have a call `r.inc()` and where `r` has type `&mut T`,
898 * then we treat that like `(&mut *r).inc()`. This avoids
899 * consuming the original pointer.
901 * You might think that this would be a natural byproduct of
902 * the auto-deref/auto-ref process. This is true for `Box<T>`
903 * but not for an `&mut T` receiver. With `Box<T>`, we would
904 * begin by testing for methods with a self type `Box<T>`,
905 * then autoderef to `T`, then autoref to `&mut T`. But with
906 * an `&mut T` receiver the process begins with `&mut T`, only
907 * without any autoadjustments.
910 let tcx = self.tcx();
911 return match ty::get(self_ty).sty {
912 ty::ty_rptr(_, self_mt) if default_method_hack(self_mt) => {
915 autoderefs: autoderefs,
918 ty::ty_rptr(_, self_mt) => {
920 self.infcx().next_region_var(infer::Autoref(self.span));
921 (ty::mk_rptr(tcx, region, self_mt),
923 autoderefs: autoderefs + 1,
924 autoref: Some(ty::AutoPtr(region, self_mt.mutbl, None))})
929 autoderefs: autoderefs,
934 fn default_method_hack(self_mt: ty::mt) -> bool {
935 // FIXME(#6129). Default methods can't deal with autoref.
937 // I am a horrible monster and I pray for death. Currently
938 // the default method code fails when you try to reborrow
939 // because it is not handling types correctly. In lieu of
940 // fixing that, I am introducing this horrible hack. - ndm
941 self_mt.mutbl == MutImmutable && ty::type_is_self(self_mt.ty)
945 // Takes an [T] - an unwrapped DST pointer (either ~ or &)
946 // [T] to &[T] or &&[T] (note that we started with a &[T] or ~[T] which has
947 // been implicitly derefed).
948 fn auto_slice_vec(&self, ty: ty::t, autoderefs: uint) -> Option<MethodCallee> {
949 let tcx = self.tcx();
950 debug!("auto_slice_vec {}", ppaux::ty_to_string(tcx, ty));
952 // First try to borrow to a slice
953 let entry = self.search_for_some_kind_of_autorefd_method(
954 |r, m| AutoPtr(r, m, None), autoderefs, [MutImmutable, MutMutable],
955 |m,r| ty::mk_slice(tcx, r,
956 ty::mt {ty:ty, mutbl:m}));
962 // Then try to borrow to a slice *and* borrow a pointer.
963 self.search_for_some_kind_of_autorefd_method(
964 |r, m| AutoPtr(r, ast::MutImmutable, Some( box AutoPtr(r, m, None))),
965 autoderefs, [MutImmutable, MutMutable],
967 let slice_ty = ty::mk_slice(tcx, r,
968 ty::mt {ty:ty, mutbl:m});
969 // NB: we do not try to autoref to a mutable
970 // pointer. That would be creating a pointer
971 // to a temporary pointer (the borrowed
972 // slice), so any update the callee makes to
973 // it can't be observed.
974 ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:MutImmutable})
978 // [T, ..len] -> [T] or &[T] or &&[T]
979 fn auto_unsize_vec(&self, ty: ty::t, autoderefs: uint, len: uint) -> Option<MethodCallee> {
980 let tcx = self.tcx();
981 debug!("auto_unsize_vec {}", ppaux::ty_to_string(tcx, ty));
983 // First try to borrow to an unsized vec.
984 let entry = self.search_for_some_kind_of_autorefd_method(
985 |_r, _m| AutoUnsize(ty::UnsizeLength(len)),
986 autoderefs, [MutImmutable, MutMutable],
987 |_m, _r| ty::mk_vec(tcx, ty, None));
993 // Then try to borrow to a slice.
994 let entry = self.search_for_some_kind_of_autorefd_method(
995 |r, m| AutoPtr(r, m, Some(box AutoUnsize(ty::UnsizeLength(len)))),
996 autoderefs, [MutImmutable, MutMutable],
997 |m, r| ty::mk_slice(tcx, r, ty::mt {ty:ty, mutbl:m}));
1003 // Then try to borrow to a slice *and* borrow a pointer.
1004 self.search_for_some_kind_of_autorefd_method(
1005 |r, m| AutoPtr(r, m,
1006 Some(box AutoPtr(r, m,
1007 Some(box AutoUnsize(ty::UnsizeLength(len)))))),
1008 autoderefs, [MutImmutable, MutMutable],
1010 let slice_ty = ty::mk_slice(tcx, r, ty::mt {ty:ty, mutbl:m});
1011 ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:MutImmutable})
1015 fn auto_slice_str(&self, autoderefs: uint) -> Option<MethodCallee> {
1016 let tcx = self.tcx();
1017 debug!("auto_slice_str");
1019 let entry = self.search_for_some_kind_of_autorefd_method(
1020 |r, m| AutoPtr(r, m, None), autoderefs, [MutImmutable],
1021 |_m, r| ty::mk_str_slice(tcx, r, MutImmutable));
1023 if entry.is_some() {
1027 self.search_for_some_kind_of_autorefd_method(
1028 |r, m| AutoPtr(r, ast::MutImmutable, Some( box AutoPtr(r, m, None))),
1029 autoderefs, [MutImmutable],
1031 let slice_ty = ty::mk_str_slice(tcx, r, m);
1032 ty::mk_rptr(tcx, r, ty::mt {ty:slice_ty, mutbl:m})
1036 // Coerce Box/&Trait instances to &Trait.
1037 fn auto_slice_trait(&self, ty: ty::t, autoderefs: uint) -> Option<MethodCallee> {
1038 debug!("auto_slice_trait");
1039 match ty::get(ty).sty {
1040 ty_trait(box ty::TyTrait {
1042 substs: ref trt_substs,
1045 let tcx = self.tcx();
1046 self.search_for_some_kind_of_autorefd_method(
1047 |r, m| AutoPtr(r, m, None),
1048 autoderefs, [MutImmutable, MutMutable],
1050 let tr = ty::mk_trait(tcx, trt_did, trt_substs.clone(), b);
1051 ty::mk_rptr(tcx, r, ty::mt{ ty: tr, mutbl: m })
1054 _ => fail!("Expected ty_trait in auto_slice_trait")
1058 fn search_for_autofatptrd_method(&self,
1061 -> Option<MethodCallee> {
1063 * Searches for a candidate by converting things like
1067 let tcx = self.tcx();
1068 debug!("search_for_autofatptrd_method {}", ppaux::ty_to_string(tcx, self_ty));
1070 let sty = ty::get(self_ty).sty.clone();
1072 ty_vec(ty, Some(len)) => self.auto_unsize_vec(ty, autoderefs, len),
1073 ty_vec(ty, None) => self.auto_slice_vec(ty, autoderefs),
1074 ty_str => self.auto_slice_str(autoderefs),
1075 ty_trait(..) => self.auto_slice_trait(self_ty, autoderefs),
1078 // This case should probably be handled similarly to
1087 fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
1088 -> Option<MethodCallee> {
1091 * Converts any type `T` to `&M T` where `M` is an
1092 * appropriate mutability.
1095 let tcx = self.tcx();
1096 match ty::get(self_ty).sty {
1097 ty_bare_fn(..) | ty_box(..) | ty_uniq(..) | ty_rptr(..) |
1098 ty_infer(IntVar(_)) |
1099 ty_infer(FloatVar(_)) |
1100 ty_param(..) | ty_nil | ty_bot | ty_bool |
1101 ty_char | ty_int(..) | ty_uint(..) |
1102 ty_float(..) | ty_enum(..) | ty_ptr(..) | ty_struct(..) |
1103 ty_unboxed_closure(..) | ty_tup(..) | ty_open(..) |
1104 ty_str | ty_vec(..) | ty_trait(..) | ty_closure(..) => {
1105 self.search_for_some_kind_of_autorefd_method(
1106 |r, m| AutoPtr(r, m, None), autoderefs, [MutImmutable, MutMutable],
1107 |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:self_ty, mutbl:m}))
1112 ty_infer(TyVar(_)) => {
1113 self.bug(format!("unexpected type: {}",
1114 self.ty_to_string(self_ty)).as_slice());
1119 fn search_for_some_kind_of_autorefd_method(
1121 kind: |Region, ast::Mutability| -> ty::AutoRef,
1123 mutbls: &[ast::Mutability],
1124 mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
1125 -> Option<MethodCallee> {
1126 // Hacky. For overloaded derefs, there may be an adjustment
1127 // added to the expression from the outside context, so we do not store
1128 // an explicit adjustment, but rather we hardwire the single deref
1129 // that occurs in trans and mem_categorization.
1130 let self_expr_id = match self.self_expr {
1131 Some(expr) => Some(expr.id),
1133 assert_eq!(autoderefs, 0);
1134 assert!(kind(ty::ReEmpty, ast::MutImmutable) ==
1135 ty::AutoPtr(ty::ReEmpty, ast::MutImmutable, None));
1140 // This is hokey. We should have mutability inference as a
1141 // variable. But for now, try &const, then &, then &mut:
1143 self.infcx().next_region_var(infer::Autoref(self.span));
1144 for mutbl in mutbls.iter() {
1145 let autoref_ty = mk_autoref_ty(*mutbl, region);
1146 match self.search_for_method(autoref_ty) {
1149 match self_expr_id {
1150 Some(self_expr_id) => {
1151 self.fcx.write_adjustment(
1153 ty::AutoDerefRef(ty::AutoDerefRef {
1154 autoderefs: autoderefs,
1155 autoref: Some(kind(region, *mutbl))
1160 return Some(method);
1167 fn search_for_method(&self, rcvr_ty: ty::t) -> Option<MethodCallee> {
1168 debug!("search_for_method(rcvr_ty={})", self.ty_to_string(rcvr_ty));
1169 let _indenter = indenter();
1171 // I am not sure that inherent methods should have higher
1172 // priority, but it is necessary ATM to handle some of the
1175 debug!("searching inherent candidates");
1176 match self.consider_candidates(rcvr_ty, self.inherent_candidates.as_slice()) {
1183 debug!("searching extension candidates");
1184 self.consider_candidates(rcvr_ty, self.extension_candidates.as_slice())
1187 fn consider_candidates(&self, rcvr_ty: ty::t,
1188 candidates: &[Candidate])
1189 -> Option<MethodCallee> {
1190 let relevant_candidates = self.filter_candidates(rcvr_ty, candidates);
1192 if relevant_candidates.len() == 0 {
1196 if self.report_statics == ReportStaticMethods {
1197 // lookup should only be called with ReportStaticMethods if a regular lookup failed
1198 assert!(relevant_candidates.iter()
1200 c.method_ty.explicit_self == ty::StaticExplicitSelfCategory
1203 self.tcx().sess.fileline_note(self.span,
1204 "found defined static methods, maybe a `self` is missing?");
1206 for (idx, candidate) in relevant_candidates.iter().enumerate() {
1207 self.report_candidate(idx, &candidate.origin);
1210 // return something so we don't get errors for every mutability
1211 return Some(MethodCallee {
1212 origin: relevant_candidates.get(0).origin,
1214 substs: subst::Substs::empty()
1218 if relevant_candidates.len() > 1 {
1219 span_err!(self.tcx().sess, self.span, E0034,
1220 "multiple applicable methods in scope");
1221 for (idx, candidate) in relevant_candidates.iter().enumerate() {
1222 self.report_candidate(idx, &candidate.origin);
1226 Some(self.confirm_candidate(rcvr_ty, relevant_candidates.get(0)))
1229 fn filter_candidates(&self, rcvr_ty: ty::t, candidates: &[Candidate]) -> Vec<Candidate> {
1230 let mut relevant_candidates: Vec<Candidate> = Vec::new();
1232 for candidate_a in candidates.iter().filter(|&c| self.is_relevant(rcvr_ty, c)) {
1233 // Skip this one if we already have one like it
1234 if !relevant_candidates.iter().any(|candidate_b| {
1235 debug!("attempting to merge {} and {}",
1236 candidate_a.repr(self.tcx()),
1237 candidate_b.repr(self.tcx()));
1238 match (&candidate_a.origin, &candidate_b.origin) {
1239 (&MethodParam(ref p1), &MethodParam(ref p2)) => {
1240 let same_trait = p1.trait_id == p2.trait_id;
1241 let same_method = p1.method_num == p2.method_num;
1242 let same_param = p1.param_num == p2.param_num;
1243 // The bound number may be different because
1244 // multiple bounds may lead to the same trait
1246 same_trait && same_method && same_param
1251 relevant_candidates.push(candidate_a.clone());
1258 fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
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.
1268 let tcx = self.tcx();
1270 debug!("confirm_candidate(rcvr_ty={}, candidate={})",
1271 self.ty_to_string(rcvr_ty),
1272 candidate.repr(self.tcx()));
1274 self.enforce_object_limitations(candidate);
1275 self.enforce_drop_trait_limitations(candidate);
1277 // static methods should never have gotten this far:
1278 assert!(candidate.method_ty.explicit_self !=
1279 ty::StaticExplicitSelfCategory);
1281 // Determine the values for the generic parameters of the method.
1282 // If they were not explicitly supplied, just construct fresh
1284 let num_supplied_tps = self.supplied_tps.len();
1285 let num_method_tps = candidate.method_ty.generics.types.len(subst::FnSpace);
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)
1298 Vec::from_slice(self.supplied_tps)
1302 // Create subst for early-bound lifetime parameters, combining
1303 // parameters from the type and those from the method.
1305 // FIXME -- permit users to manually specify lifetimes
1307 self.fcx.infcx().region_vars_for_defs(
1309 candidate.method_ty.generics.regions.get_slice(subst::FnSpace));
1311 let all_substs = candidate.rcvr_substs.clone().with_method(m_types, m_regions);
1313 let ref bare_fn_ty = candidate.method_ty.fty;
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));
1320 let fn_sig = &bare_fn_ty.sig;
1321 let inputs = match candidate.origin {
1322 MethodObject(..) => {
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)
1328 Some(*fn_sig.inputs.get(0)).move_iter().chain(args).collect()
1330 _ => fn_sig.inputs.subst(tcx, &all_substs)
1332 let fn_sig = ty::FnSig {
1333 binder_id: fn_sig.binder_id,
1335 output: fn_sig.output.subst(tcx, &all_substs),
1336 variadic: fn_sig.variadic
1339 debug!("after subst, fty={}", fn_sig.repr(tcx));
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(
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 {
1350 fn_style: bare_fn_ty.fn_style,
1351 abi: bare_fn_ty.abi.clone(),
1353 debug!("after replacing bound regions, fty={}", self.ty_to_string(fty));
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) {
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());
1372 self.fcx.add_region_obligations_for_parameters(
1375 &candidate.method_ty.generics);
1378 origin: candidate.origin,
1384 fn enforce_object_limitations(&self, candidate: &Candidate) {
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.
1393 match candidate.origin {
1396 MethodStaticUnboxedClosure(..) => {
1397 return; // not a call to a trait instance
1399 MethodObject(..) => {}
1402 match candidate.method_ty.explicit_self {
1403 ty::StaticExplicitSelfCategory => { // reason (a) above
1404 self.tcx().sess.span_err(
1406 "cannot call a method without a receiver \
1407 through an object");
1410 ty::ByValueExplicitSelfCategory |
1411 ty::ByReferenceExplicitSelfCategory(..) |
1412 ty::ByBoxExplicitSelfCategory => {}
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");
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;
1435 check_for_self_ty(sig.output);
1438 if candidate.method_ty.generics.has_type_params(subst::FnSpace) {
1440 span_err!(self.tcx().sess, self.span, E0039,
1441 "cannot call a generic method through an object");
1445 fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
1446 // No code can call the finalize method explicitly.
1448 match candidate.origin {
1449 MethodStatic(method_id) => {
1450 bad = self.tcx().destructors.borrow().contains(&method_id);
1452 MethodStaticUnboxedClosure(_) => bad = false,
1453 // FIXME: does this properly enforce this on everything now
1454 // that self has been merged in? -sully
1455 MethodParam(MethodParam { trait_id: trait_id, .. }) |
1456 MethodObject(MethodObject { trait_id: trait_id, .. }) => {
1457 bad = self.tcx().destructor_for_type.borrow()
1458 .contains_key(&trait_id);
1463 span_err!(self.tcx().sess, self.span, E0040,
1464 "explicit call to destructor");
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()));
1474 return match candidate.method_ty.explicit_self {
1475 StaticExplicitSelfCategory => {
1476 debug!("(is relevant?) explicit self is static");
1477 self.report_statics == ReportStaticMethods
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 {
1489 rcvr_matches_object(self_did, candidate) ||
1490 rcvr_matches_ty(self.fcx,
1495 rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
1499 _ => rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
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)
1512 _ => mutability_matches(mt.mutbl, m) &&
1513 rcvr_matches_ty(self.fcx, mt.ty, candidate)
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)
1529 _ => rcvr_matches_ty(self.fcx, typ, candidate),
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
1544 RcvrMatchesIfSubtype(_) | RcvrMatchesIfEqtype(_) => {
1550 fn rcvr_matches_ty(fcx: &FnCtxt,
1552 candidate: &Candidate) -> bool {
1553 match candidate.rcvr_match_condition {
1554 RcvrMatchesIfObject(_) => {
1557 RcvrMatchesIfSubtype(of_type) => {
1558 fcx.can_mk_subty(rcvr_ty, of_type).is_ok()
1560 RcvrMatchesIfEqtype(of_type) => {
1561 fcx.can_mk_eqty(rcvr_ty, of_type).is_ok()
1566 fn mutability_matches(self_mutbl: ast::Mutability,
1567 candidate_mutbl: ast::Mutability)
1569 //! True if `self_mutbl <: candidate_mutbl`
1570 self_mutbl == candidate_mutbl
1574 fn report_candidate(&self, idx: uint, origin: &MethodOrigin) {
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) {
1582 debug!("(report candidate) No trait method \
1586 Some(MethodTraitItemId(trait_did)) => {
1587 debug!("(report candidate) Found trait ref");
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) {
1599 self.report_static_candidate(idx, did)
1601 MethodStaticUnboxedClosure(did) => {
1602 self.report_static_candidate(idx, did)
1604 MethodParam(ref mp) => {
1605 self.report_param_candidate(idx, (*mp).trait_id)
1607 MethodObject(ref mo) => {
1608 self.report_trait_candidate(idx, mo.trait_id)
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)
1619 span_note!(self.tcx().sess, span,
1620 "candidate #{} is `{}`",
1621 idx + 1u, ty::item_path_str(self.tcx(), did));
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));
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));
1637 fn infcx(&'a self) -> &'a infer::InferCtxt<'a, 'tcx> {
1641 fn tcx(&self) -> &'a ty::ctxt<'tcx> {
1645 fn ty_to_string(&self, t: ty::t) -> String {
1646 self.fcx.infcx().ty_to_string(t)
1649 fn did_to_string(&self, did: DefId) -> String {
1650 ty::item_path_str(self.tcx(), did)
1653 fn bug(&self, s: &str) -> ! {
1654 self.tcx().sess.span_bug(self.span, s)
1658 impl Repr for Candidate {
1659 fn repr(&self, tcx: &ty::ctxt) -> String {
1660 format!("Candidate(rcvr_ty={}, rcvr_substs={}, method_ty={}, \
1662 self.rcvr_match_condition.repr(tcx),
1663 self.rcvr_substs.repr(tcx),
1664 self.method_ty.repr(tcx),
1669 impl Repr for RcvrMatchCondition {
1670 fn repr(&self, tcx: &ty::ctxt) -> String {
1672 RcvrMatchesIfObject(d) => {
1673 format!("RcvrMatchesIfObject({})", d.repr(tcx))
1675 RcvrMatchesIfSubtype(t) => {
1676 format!("RcvrMatchesIfSubtype({})", t.repr(tcx))
1678 RcvrMatchesIfEqtype(t) => {
1679 format!("RcvrMatchesIfEqtype({})", t.repr(tcx))