(index<- )        ./librustc/middle/typeck/check/method.rs

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


librustc/middle/typeck/check/method.rs:1413:8-1413:8 -fn- definition:
        fn rcvr_matches_ty(fcx: &FnCtxt,
                           rcvr_ty: ty::t,
                           candidate: &Candidate) -> bool {
references:- 3
1385:                             ty::ty_vec(_, None) | ty::ty_str => false,
1386:                             _ => rcvr_matches_ty(self.fcx, typ, candidate),
1387:                         }


librustc/middle/typeck/check/method.rs:115:16-115:16 -enum- definition:
pub enum AutoderefReceiverFlag {
    AutoderefReceiver,
    DontAutoderefReceiver,
references:- 7
310:     check_traits: CheckTraitsFlag,
311:     autoderef_receiver: AutoderefReceiverFlag,
312:     report_statics: StaticMethodsFlag,
librustc/middle/typeck/check/mod.rs:
2052:                         args: &[@ast::Expr],
2053:                         autoderef_receiver: AutoderefReceiverFlag,
2054:                         unbound_method: ||) -> ty::t {


librustc/middle/typeck/check/method.rs:319:19-319:19 -struct- definition:
struct Candidate {
    rcvr_match_condition: RcvrMatchCondition,
    rcvr_substs: ty::substs,
references:- 21
318:  */
320: struct Candidate {
--
714:         candidates.push(Candidate {
715:             rcvr_match_condition: RcvrMatchesIfSubtype(impl_ty),
--
1076:     fn merge_candidates(&self, candidates: &[Candidate]) -> Vec<Candidate> {
1077:         let mut merged = Vec::new();
--
1320:     fn enforce_drop_trait_limitations(&self, candidate: &Candidate) {
1321:         // No code can call the finalize method explicitly.
--
1401:         fn rcvr_matches_object(self_did: ast::DefId,
1402:                                candidate: &Candidate) -> bool {
1403:             match candidate.rcvr_match_condition {
--
1514: impl Repr for Candidate {
1515:     fn repr(&self, tcx: &ty::ctxt) -> ~str {


librustc/middle/typeck/check/method.rs:1401:8-1401:8 -fn- definition:
        fn rcvr_matches_object(self_did: ast::DefId,
                               candidate: &Candidate) -> bool {
            match candidate.rcvr_match_condition {
references:- 2
1372:                         mutability_matches(self_m, m) &&
1373:                         rcvr_matches_object(self_did, candidate)
1374:                     }
--
1392:                     }) => {
1393:                         rcvr_matches_object(self_did, candidate)
1394:                     }


librustc/middle/typeck/check/method.rs:126:1-126:1 -fn- definition:
pub fn lookup<'a>(
        fcx: &'a FnCtxt<'a>,
        // In a call `a.b::<X, Y, ...>(...)`:
references:- 3
librustc/middle/typeck/check/mod.rs:
1986:                 // Check for potential static matches (missing self parameters)
1987:                 method::lookup(fcx, expr, rcvr,
1988:                                     method_name.node.name,
--
2377:         let tps: Vec<ty::t> = tys.iter().map(|&ty| fcx.to_ty(ty)).collect();
2378:         match method::lookup(fcx,
2379:                              expr,


librustc/middle/typeck/check/method.rs:109:16-109:16 -enum- definition:
pub enum CheckTraitsFlag {
    CheckTraitsOnly,
    CheckTraitsAndInherentMethods,
references:- 5
136:         deref_args: check::DerefArgs,       // Whether we autopointer first.
137:         check_traits: CheckTraitsFlag,      // Whether we check traits only.
138:         autoderef_receiver: AutoderefReceiverFlag,
--
309:     deref_args: check::DerefArgs,
310:     check_traits: CheckTraitsFlag,
311:     autoderef_receiver: AutoderefReceiverFlag,


librustc/middle/typeck/check/method.rs:173:1-173:1 -fn- definition:
pub fn lookup_in_trait<'a>(
        fcx: &'a FnCtxt<'a>,
        // In a call `a.b::<X, Y, ...>(...)`:
references:- 3
librustc/middle/typeck/check/mod.rs:
1376:         (None, Some(trait_did)) => {
1377:             method::lookup_in_trait(fcx, span, base_expr.map(|x| &*x),
1378:                                     token::intern("deref"), trait_did,
--
2056:             Some(trait_did) => {
2057:                 method::lookup_in_trait(fcx, op_ex.span, Some(&*args[0]), opname,
2058:                                         trait_did, self_t, [], autoderef_receiver,


librustc/middle/typeck/check/method.rs:1426:8-1426:8 -fn- definition:
        fn mutability_matches(self_mutbl: ast::Mutability,
                              candidate_mutbl: ast::Mutability)
                              -> bool {
references:- 2
1363:                             ty::ty_vec(_, None) | ty::ty_str => false,
1364:                             _ => mutability_matches(mt.mutbl, m) &&
1365:                                  rcvr_matches_ty(self.fcx, mt.ty, candidate),
--
1371:                     }) => {
1372:                         mutability_matches(self_m, m) &&
1373:                         rcvr_matches_object(self_did, candidate)


librustc/middle/typeck/check/method.rs:121:16-121:16 -enum- definition:
pub enum StaticMethodsFlag {
    ReportStaticMethods,
    IgnoreStaticMethods,
references:- 6
122: pub enum StaticMethodsFlag {
--
184:         autoderef_receiver: AutoderefReceiverFlag,
185:         report_statics: StaticMethodsFlag)
186:      -> Option<MethodCallee> {
--
311:     autoderef_receiver: AutoderefReceiverFlag,
312:     report_statics: StaticMethodsFlag,
313: }


librustc/middle/typeck/check/method.rs:293:1-293:1 -struct- definition:
struct LookupContext<'a> {
    fcx: &'a FnCtxt<'a>,
    span: Span,
references:- 3
140:      -> Option<MethodCallee> {
141:     let mut lcx = LookupContext {
142:         fcx: fcx,
--
341: impl<'a> LookupContext<'a> {
342:     fn search(&self, self_ty: ty::t) -> Option<MethodCallee> {


librustc/middle/typeck/check/method.rs:335:19-335:19 -enum- definition:
pub enum RcvrMatchCondition {
    RcvrMatchesIfObject(ast::DefId),
    RcvrMatchesIfSubtype(ty::t)
references:- 4
334: /// because traits are not types, this is a pain to do.
336: pub enum RcvrMatchCondition {
--
1524: impl Repr for RcvrMatchCondition {
1525:     fn repr(&self, tcx: &ty::ctxt) -> ~str {