1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
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.
11 use super::{MethodError,Ambiguity,NoMatch};
12 use super::MethodIndex;
13 use super::{CandidateSource,ImplSource,TraitSource};
15 use middle::fast_reject;
17 use middle::subst::Subst;
19 use middle::ty::{mod, Ty};
20 use middle::ty_fold::HigherRankedFoldable;
21 use middle::typeck::check;
22 use middle::typeck::check::{FnCtxt, NoPreference};
23 use middle::typeck::{MethodObject};
24 use middle::typeck::infer;
25 use middle::typeck::infer::InferCtxt;
27 use syntax::codemap::{Span, DUMMY_SP};
28 use std::collections::HashSet;
30 use util::ppaux::Repr;
32 use self::CandidateKind::*;
33 pub use self::PickAdjustment::*;
34 pub use self::PickKind::*;
36 struct ProbeContext<'a, 'tcx:'a> {
37 fcx: &'a FnCtxt<'a, 'tcx>,
39 method_name: ast::Name,
40 steps: Rc<Vec<CandidateStep<'tcx>>>,
41 opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>,
42 inherent_candidates: Vec<Candidate<'tcx>>,
43 extension_candidates: Vec<Candidate<'tcx>>,
44 impl_dups: HashSet<ast::DefId>,
45 static_candidates: Vec<CandidateSource>,
48 struct CandidateStep<'tcx> {
50 adjustment: PickAdjustment,
53 struct Candidate<'tcx> {
54 xform_self_ty: Ty<'tcx>,
55 method_ty: Rc<ty::Method<'tcx>>,
56 kind: CandidateKind<'tcx>,
59 enum CandidateKind<'tcx> {
60 InherentImplCandidate(/* Impl */ ast::DefId, subst::Substs<'tcx>),
61 ObjectCandidate(MethodObject<'tcx>),
62 ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>,
63 subst::Substs<'tcx>, MethodIndex),
64 UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
65 WhereClauseCandidate(Rc<ty::TraitRef<'tcx>>, MethodIndex),
68 pub struct Pick<'tcx> {
69 pub method_ty: Rc<ty::Method<'tcx>>,
70 pub adjustment: PickAdjustment,
71 pub kind: PickKind<'tcx>,
74 #[deriving(Clone,Show)]
75 pub enum PickKind<'tcx> {
76 InherentImplPick(/* Impl */ ast::DefId),
77 ObjectPick(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint),
78 ExtensionImplPick(/* Impl */ ast::DefId, MethodIndex),
79 TraitPick(/* Trait */ ast::DefId, MethodIndex),
80 WhereClausePick(/* Trait */ Rc<ty::TraitRef<'tcx>>, MethodIndex),
83 pub type PickResult<'tcx> = Result<Pick<'tcx>, MethodError>;
85 // This is a kind of "abstracted" version of ty::AutoAdjustment. The
86 // difference is that it doesn't embed any regions or other
87 // specifics. The "confirmation" step recreates those details as
89 #[deriving(Clone,Show)]
90 pub enum PickAdjustment {
91 // Indicates that the source expression should be autoderef'd N times
93 // A = expr | *expr | **expr
96 // Indicates that the source expression should be autoderef'd N
97 // times and then "unsized". This should probably eventually go
98 // away in favor of just coercing method receivers.
100 // A = unsize(expr | *expr | **expr)
101 AutoUnsizeLength(/* number of autoderefs */ uint, /* length*/ uint),
103 // Indicates that an autoref is applied after some number of other adjustments
106 AutoRef(ast::Mutability, Box<PickAdjustment>),
109 pub fn probe<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
111 method_name: ast::Name,
113 call_expr_id: ast::NodeId)
116 debug!("probe(self_ty={}, method_name={}, call_expr_id={})",
117 self_ty.repr(fcx.tcx()),
121 // FIXME(#18741) -- right now, creating the steps involves evaluating the
122 // `*` operator, which registers obligations that then escape into
123 // the global fulfillment context and thus has global
124 // side-effects. This is a bit of a pain to refactor. So just let
125 // it ride, although it's really not great, and in fact could I
126 // think cause spurious errors. Really though this part should
127 // take place in the `fcx.infcx().probe` below.
128 let steps = create_steps(fcx, span, self_ty);
130 // Create a list of simplified self types, if we can.
131 let mut simplified_steps = Vec::new();
132 for step in steps.iter() {
133 match fast_reject::simplify_type(fcx.tcx(), step.self_ty, true) {
135 Some(simplified_type) => { simplified_steps.push(simplified_type); }
138 let opt_simplified_steps =
139 if simplified_steps.len() < steps.len() {
140 None // failed to convert at least one of the steps
142 Some(simplified_steps)
145 debug!("ProbeContext: steps for self_ty={} are {}",
146 self_ty.repr(fcx.tcx()),
147 steps.repr(fcx.tcx()));
149 // this creates one big transaction so that all type variables etc
150 // that we create during the probe process are removed later
151 let mut dummy = Some((steps, opt_simplified_steps)); // FIXME(#18101) need once closures
152 fcx.infcx().probe(|| {
153 let (steps, opt_simplified_steps) = dummy.take().unwrap();
154 let mut probe_cx = ProbeContext::new(fcx, span, method_name, steps, opt_simplified_steps);
155 probe_cx.assemble_inherent_candidates();
156 probe_cx.assemble_extension_candidates_for_traits_in_scope(call_expr_id);
161 fn create_steps<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
164 -> Vec<CandidateStep<'tcx>> {
165 let mut steps = Vec::new();
167 let (fully_dereferenced_ty, dereferences, _) =
169 fcx, span, self_ty, None, NoPreference,
171 let adjustment = consider_reborrow(t, d);
172 steps.push(CandidateStep { self_ty: t, adjustment: adjustment });
173 None::<()> // keep iterating until we can't anymore
176 match fully_dereferenced_ty.sty {
177 ty::ty_vec(elem_ty, Some(len)) => {
178 steps.push(CandidateStep {
179 self_ty: ty::mk_vec(fcx.tcx(), elem_ty, None),
180 adjustment: AutoUnsizeLength(dereferences, len),
189 fn consider_reborrow(ty: Ty, d: uint) -> PickAdjustment {
190 // Insert a `&*` or `&mut *` if this is a reference type:
192 ty::ty_rptr(_, ref mt) => AutoRef(mt.mutbl, box AutoDeref(d+1)),
198 impl<'a,'tcx> ProbeContext<'a,'tcx> {
199 fn new(fcx: &'a FnCtxt<'a,'tcx>,
201 method_name: ast::Name,
202 steps: Vec<CandidateStep<'tcx>>,
203 opt_simplified_steps: Option<Vec<fast_reject::SimplifiedType>>)
204 -> ProbeContext<'a,'tcx>
209 method_name: method_name,
210 inherent_candidates: Vec::new(),
211 extension_candidates: Vec::new(),
212 impl_dups: HashSet::new(),
213 steps: Rc::new(steps),
214 opt_simplified_steps: opt_simplified_steps,
215 static_candidates: Vec::new(),
219 fn tcx(&self) -> &'a ty::ctxt<'tcx> {
223 fn infcx(&self) -> &'a InferCtxt<'a, 'tcx> {
227 ///////////////////////////////////////////////////////////////////////////
228 // CANDIDATE ASSEMBLY
230 fn assemble_inherent_candidates(&mut self) {
231 let steps = self.steps.clone();
232 for step in steps.iter() {
233 self.assemble_probe(step.self_ty);
237 fn assemble_probe(&mut self, self_ty: Ty<'tcx>) {
238 debug!("assemble_probe: self_ty={}",
239 self_ty.repr(self.tcx()));
242 ty::ty_trait(box ty::TyTrait { ref principal, bounds, .. }) => {
243 self.assemble_inherent_candidates_from_object(self_ty, &*principal, bounds);
244 self.assemble_inherent_impl_candidates_for_type(principal.def_id);
246 ty::ty_enum(did, _) |
247 ty::ty_struct(did, _) |
248 ty::ty_unboxed_closure(did, _, _) => {
249 self.assemble_inherent_impl_candidates_for_type(did);
252 self.assemble_inherent_candidates_from_param(self_ty, p);
259 fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) {
260 // Read the inherent implementation candidates for this type from the
261 // metadata if necessary.
262 ty::populate_implementations_for_type_if_necessary(self.tcx(), def_id);
264 for impl_infos in self.tcx().inherent_impls.borrow().get(&def_id).iter() {
265 for &impl_def_id in impl_infos.iter() {
266 self.assemble_inherent_impl_probe(impl_def_id);
271 fn assemble_inherent_impl_probe(&mut self, impl_def_id: ast::DefId) {
272 if !self.impl_dups.insert(impl_def_id) {
273 return; // already visited
276 let method = match impl_method(self.tcx(), impl_def_id, self.method_name) {
278 None => { return; } // No method with correct name on this impl
281 if !self.has_applicable_self(&*method) {
282 // No receiver declared. Not a candidate.
283 return self.record_static_candidate(ImplSource(impl_def_id));
286 let impl_substs = self.impl_substs(impl_def_id);
288 // Determine the receiver type that the method itself expects.
290 self.xform_self_ty(&method, &impl_substs);
292 self.inherent_candidates.push(Candidate {
293 xform_self_ty: xform_self_ty,
295 kind: InherentImplCandidate(impl_def_id, impl_substs)
299 fn assemble_inherent_candidates_from_object(&mut self,
301 principal: &ty::TraitRef<'tcx>,
302 _bounds: ty::ExistentialBounds) {
303 debug!("assemble_inherent_candidates_from_object(self_ty={})",
304 self_ty.repr(self.tcx()));
306 let tcx = self.tcx();
308 // It is illegal to invoke a method on a trait instance that
309 // refers to the `Self` type. An error will be reported by
310 // `enforce_object_limitations()` if the method refers to the
311 // `Self` type anywhere other than the receiver. Here, we use
312 // a substitution that replaces `Self` with the object type
313 // itself. Hence, a `&self` method will wind up with an
314 // argument type like `&Trait`.
315 let rcvr_substs = principal.substs.clone().with_self_ty(self_ty);
316 let trait_ref = Rc::new(ty::TraitRef {
317 def_id: principal.def_id,
318 substs: rcvr_substs.clone()
321 self.elaborate_bounds(&[trait_ref.clone()], |this, new_trait_ref, m, method_num| {
323 get_method_index(tcx, &*new_trait_ref,
324 trait_ref.clone(), method_num);
326 // FIXME Hacky. By-value `self` methods in objects ought to be
327 // just a special case of passing ownership of a DST value
328 // as a parameter. *But* we currently hack them in and tie them to
329 // the particulars of the `Box` type. So basically for a `fn foo(self,...)`
330 // method invoked on an object, we don't want the receiver type to be
331 // `TheTrait`, but rather `Box<TheTrait>`. Yuck.
333 match m.explicit_self {
334 ty::ByValueExplicitSelfCategory => {
335 let mut n = (*m).clone();
336 let self_ty = n.fty.sig.inputs[0];
337 n.fty.sig.inputs[0] = ty::mk_uniq(tcx, self_ty);
344 this.xform_self_ty(&m, &new_trait_ref.substs);
346 this.inherent_candidates.push(Candidate {
347 xform_self_ty: xform_self_ty,
349 kind: ObjectCandidate(MethodObject {
350 trait_ref: new_trait_ref,
351 object_trait_id: principal.def_id,
352 method_num: method_num,
353 real_index: vtable_index
359 fn assemble_inherent_candidates_from_param(&mut self,
361 param_ty: ty::ParamTy) {
362 // FIXME -- Do we want to commit to this behavior for param bounds?
364 let ty::ParamTy { space, idx: index, .. } = param_ty;
366 self.fcx.inh.param_env.bounds.get(space, index).trait_bounds
368 self.elaborate_bounds(bounds, |this, trait_ref, m, method_num| {
370 this.xform_self_ty(&m, &trait_ref.substs);
372 debug!("found match: trait_ref={} substs={} m={}",
373 trait_ref.repr(this.tcx()),
374 trait_ref.substs.repr(this.tcx()),
376 assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
377 trait_ref.substs.types.get_slice(subst::TypeSpace).len());
378 assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
379 trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
380 assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
381 trait_ref.substs.types.get_slice(subst::SelfSpace).len());
382 assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
383 trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
385 // Because this trait derives from a where-clause, it
386 // should not contain any inference variables or other
387 // artifacts. This means it is safe to put into the
388 // `WhereClauseCandidate` and (eventually) into the
389 // `WhereClausePick`.
390 assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t)));
392 this.inherent_candidates.push(Candidate {
393 xform_self_ty: xform_self_ty,
395 kind: WhereClauseCandidate(trait_ref, method_num)
400 // Do a search through a list of bounds, using a callback to actually
401 // create the candidates.
404 bounds: &[Rc<ty::TraitRef<'tcx>>],
405 mk_cand: for<'a> |this: &mut ProbeContext<'a, 'tcx>,
406 tr: Rc<ty::TraitRef<'tcx>>,
407 m: Rc<ty::Method<'tcx>>,
410 let tcx = self.tcx();
411 let mut cache = HashSet::new();
412 for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
413 // Already visited this trait, skip it.
414 if !cache.insert(bound_trait_ref.def_id) {
418 let (pos, method) = match trait_method(tcx, bound_trait_ref.def_id, self.method_name) {
420 None => { continue; }
423 if !self.has_applicable_self(&*method) {
424 self.record_static_candidate(TraitSource(bound_trait_ref.def_id));
426 mk_cand(self, bound_trait_ref, method, pos);
431 fn assemble_extension_candidates_for_traits_in_scope(&mut self,
432 expr_id: ast::NodeId)
434 let mut duplicates = HashSet::new();
435 let opt_applicable_traits = self.fcx.ccx.trait_map.get(&expr_id);
436 for applicable_traits in opt_applicable_traits.into_iter() {
437 for &trait_did in applicable_traits.iter() {
438 if duplicates.insert(trait_did) {
439 self.assemble_extension_candidates_for_trait(trait_did);
445 fn assemble_extension_candidates_for_trait(&mut self,
446 trait_def_id: ast::DefId) {
447 debug!("assemble_extension_candidates_for_trait: trait_def_id={}",
448 trait_def_id.repr(self.tcx()));
450 // Check whether `trait_def_id` defines a method with suitable name:
452 ty::trait_items(self.tcx(), trait_def_id);
455 .position(|item| item.name() == self.method_name);
456 let matching_index = match matching_index {
460 let method = match (&*trait_items)[matching_index].as_opt_method() {
465 // Check whether `trait_def_id` defines a method with suitable name:
466 if !self.has_applicable_self(&*method) {
467 debug!("method has inapplicable self");
468 return self.record_static_candidate(TraitSource(trait_def_id));
471 self.assemble_extension_candidates_for_trait_impls(trait_def_id,
475 self.assemble_unboxed_closure_candidates(trait_def_id,
480 fn assemble_extension_candidates_for_trait_impls(&mut self,
481 trait_def_id: ast::DefId,
482 method: Rc<ty::Method<'tcx>>,
485 ty::populate_implementations_for_trait_if_necessary(self.tcx(),
488 let trait_impls = self.tcx().trait_impls.borrow();
489 let impl_def_ids = match trait_impls.get(&trait_def_id) {
491 Some(impls) => impls,
494 for &impl_def_id in impl_def_ids.borrow().iter() {
495 debug!("assemble_extension_candidates_for_trait_impl: trait_def_id={} impl_def_id={}",
496 trait_def_id.repr(self.tcx()),
497 impl_def_id.repr(self.tcx()));
499 if !self.impl_can_possibly_match(impl_def_id) {
503 let impl_substs = self.impl_substs(impl_def_id);
505 debug!("impl_substs={}", impl_substs.repr(self.tcx()));
508 ty::impl_trait_ref(self.tcx(), impl_def_id)
509 .unwrap() // we know this is a trait impl
510 .subst(self.tcx(), &impl_substs);
512 debug!("impl_trait_ref={}", impl_trait_ref.repr(self.tcx()));
514 // Determine the receiver type that the method itself expects.
516 self.xform_self_ty(&method, &impl_trait_ref.substs);
518 debug!("xform_self_ty={}", xform_self_ty.repr(self.tcx()));
520 self.extension_candidates.push(Candidate {
521 xform_self_ty: xform_self_ty,
522 method_ty: method.clone(),
523 kind: ExtensionImplCandidate(impl_def_id, impl_trait_ref, impl_substs, method_index)
528 fn impl_can_possibly_match(&self, impl_def_id: ast::DefId) -> bool {
529 let simplified_steps = match self.opt_simplified_steps {
530 Some(ref simplified_steps) => simplified_steps,
531 None => { return true; }
534 let impl_type = ty::lookup_item_type(self.tcx(), impl_def_id);
535 let impl_simplified_type =
536 match fast_reject::simplify_type(self.tcx(), impl_type.ty, false) {
537 Some(simplified_type) => simplified_type,
538 None => { return true; }
541 simplified_steps.contains(&impl_simplified_type)
544 fn assemble_unboxed_closure_candidates(&mut self,
545 trait_def_id: ast::DefId,
546 method_ty: Rc<ty::Method<'tcx>>,
549 // Check if this is one of the Fn,FnMut,FnOnce traits.
550 let tcx = self.tcx();
551 let kind = if Some(trait_def_id) == tcx.lang_items.fn_trait() {
552 ty::FnUnboxedClosureKind
553 } else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
554 ty::FnMutUnboxedClosureKind
555 } else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
556 ty::FnOnceUnboxedClosureKind
561 // Check if there is an unboxed-closure self-type in the list of receivers.
562 // If so, add "synthetic impls".
563 let steps = self.steps.clone();
564 for step in steps.iter() {
565 let (closure_def_id, _, _) = match step.self_ty.sty {
566 ty::ty_unboxed_closure(a, b, ref c) => (a, b, c),
570 let unboxed_closures = self.fcx.inh.unboxed_closures.borrow();
571 let closure_data = match unboxed_closures.get(&closure_def_id) {
574 self.tcx().sess.span_bug(
576 format!("No entry for unboxed closure: {}",
577 closure_def_id.repr(self.tcx())).as_slice());
581 // this closure doesn't implement the right kind of `Fn` trait
582 if closure_data.kind != kind {
586 // create some substitutions for the argument/return type;
587 // for the purposes of our method lookup, we only take
588 // receiver type into account, so we can just substitute
589 // fresh types here to use during substitution and subtyping.
590 let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
591 let substs = self.infcx().fresh_substs_for_trait(self.span,
595 let xform_self_ty = self.xform_self_ty(&method_ty, &substs);
596 self.inherent_candidates.push(Candidate {
597 xform_self_ty: xform_self_ty,
598 method_ty: method_ty.clone(),
599 kind: UnboxedClosureCandidate(trait_def_id, method_index)
604 ///////////////////////////////////////////////////////////////////////////
607 fn pick(mut self) -> PickResult<'tcx> {
608 let steps = self.steps.clone();
610 for step in steps.iter() {
611 match self.pick_step(step) {
619 Err(NoMatch(self.static_candidates))
622 fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option<PickResult<'tcx>> {
623 debug!("pick_step: step={}", step.repr(self.tcx()));
625 if ty::type_is_error(step.self_ty) {
629 match self.pick_adjusted_method(step) {
630 Some(result) => return Some(result),
634 match self.pick_autorefd_method(step) {
635 Some(result) => return Some(result),
639 // FIXME -- Super hack. For DST types, we will convert to
640 // &&[T] or &&str, as part of a kind of legacy lookup scheme.
641 match step.self_ty.sty {
642 ty::ty_str | ty::ty_vec(_, None) => self.pick_autorefrefd_method(step),
647 fn pick_adjusted_method(&mut self,
648 step: &CandidateStep<'tcx>)
649 -> Option<PickResult<'tcx>>
651 self.pick_method(step.self_ty).map(|r| self.adjust(r, step.adjustment.clone()))
654 fn pick_autorefd_method(&mut self,
655 step: &CandidateStep<'tcx>)
656 -> Option<PickResult<'tcx>>
658 let tcx = self.tcx();
659 self.search_mutabilities(
660 |m| AutoRef(m, box step.adjustment.clone()),
661 |m,r| ty::mk_rptr(tcx, r, ty::mt {ty:step.self_ty, mutbl:m}))
664 fn pick_autorefrefd_method(&mut self,
665 step: &CandidateStep<'tcx>)
666 -> Option<PickResult<'tcx>>
668 let tcx = self.tcx();
669 self.search_mutabilities(
670 |m| AutoRef(m, box AutoRef(m, box step.adjustment.clone())),
671 |m,r| ty::mk_rptr(tcx, r, ty::mt { ty: ty::mk_rptr(tcx, r, ty::mt { ty:step.self_ty,
676 fn search_mutabilities(&mut self,
677 mk_adjustment: |ast::Mutability| -> PickAdjustment,
678 mk_autoref_ty: |ast::Mutability, ty::Region| -> Ty<'tcx>)
679 -> Option<PickResult<'tcx>>
681 // In general, during probing we erase regions. See
682 // `impl_self_ty()` for an explanation.
683 let region = ty::ReStatic;
685 // Search through mutabilities in order to find one where pick works:
686 [ast::MutImmutable, ast::MutMutable]
689 let autoref_ty = mk_autoref_ty(m, region);
690 self.pick_method(autoref_ty)
691 .map(|r| self.adjust(r, mk_adjustment(m)))
698 result: PickResult<'tcx>,
699 adjustment: PickAdjustment)
700 -> PickResult<'tcx> {
704 pick.adjustment = adjustment;
710 fn pick_method(&mut self, self_ty: Ty<'tcx>) -> Option<PickResult<'tcx>> {
711 debug!("pick_method(self_ty={})", self.infcx().ty_to_string(self_ty));
713 debug!("searching inherent candidates");
714 match self.consider_candidates(self_ty, self.inherent_candidates[]) {
721 debug!("searching extension candidates");
722 self.consider_candidates(self_ty, self.extension_candidates[])
725 fn consider_candidates(&self,
727 probes: &[Candidate<'tcx>])
728 -> Option<PickResult<'tcx>> {
729 let mut applicable_candidates: Vec<_> =
731 .filter(|&probe| self.consider_probe(self_ty, probe))
734 debug!("applicable_candidates: {}", applicable_candidates.repr(self.tcx()));
736 if applicable_candidates.len() > 1 {
737 match self.collapse_candidates_to_trait_pick(applicable_candidates[]) {
738 Some(pick) => { return Some(Ok(pick)); }
743 if applicable_candidates.len() > 1 {
744 let sources = probes.iter().map(|p| p.to_source()).collect();
745 return Some(Err(Ambiguity(sources)));
748 applicable_candidates.pop().map(|probe| {
749 let pick = probe.to_unadjusted_pick();
754 fn consider_probe(&self, self_ty: Ty<'tcx>, probe: &Candidate<'tcx>) -> bool {
755 debug!("consider_probe: self_ty={} probe={}",
756 self_ty.repr(self.tcx()),
757 probe.repr(self.tcx()));
759 self.infcx().probe(|| {
760 // First check that the self type can be related.
761 match self.make_sub_ty(self_ty, probe.xform_self_ty) {
764 debug!("--> cannot relate self-types");
769 // If so, impls may carry other conditions (e.g., where
770 // clauses) that must be considered. Make sure that those
771 // match as well (or at least may match, sometimes we
772 // don't have enough information to fully evaluate).
774 InherentImplCandidate(impl_def_id, ref substs) |
775 ExtensionImplCandidate(impl_def_id, _, ref substs, _) => {
776 // Check whether the impl imposes obligations we have to worry about.
777 let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
778 let impl_bounds = impl_generics.to_bounds(self.tcx(), substs);
780 // Erase any late-bound regions bound in the impl
781 // which appear in the bounds.
782 let impl_bounds = self.erase_late_bound_regions(&ty::bind(impl_bounds)).value;
784 // Convert the bounds into obligations.
786 traits::obligations_for_generics(
788 traits::ObligationCause::misc(self.span),
791 debug!("impl_obligations={}", obligations.repr(self.tcx()));
793 // Evaluate those obligations to see if they might possibly hold.
794 let mut selcx = traits::SelectionContext::new(self.infcx(),
795 &self.fcx.inh.param_env,
797 obligations.all(|o| selcx.evaluate_obligation(o))
800 ObjectCandidate(..) |
801 UnboxedClosureCandidate(..) |
802 WhereClauseCandidate(..) => {
803 // These have no additional conditions to check.
810 /// Sometimes we get in a situation where we have multiple probes that are all impls of the
811 /// same trait, but we don't know which impl to use. In this case, since in all cases the
812 /// external interface of the method can be determined from the trait, it's ok not to decide.
813 /// We can basically just collapse all of the probes for various impls into one where-clause
814 /// probe. This will result in a pending obligation so when more type-info is available we can
815 /// make the final decision.
817 /// Example (`src/test/run-pass/method-two-trait-defer-resolution-1.rs`):
820 /// trait Foo { ... }
821 /// impl Foo for Vec<int> { ... }
822 /// impl Foo for Vec<uint> { ... }
825 /// Now imagine the receiver is `Vec<_>`. It doesn't really matter at this time which impl we
826 /// use, so it's ok to just commit to "using the method from the trait Foo".
827 fn collapse_candidates_to_trait_pick(&self,
828 probes: &[&Candidate<'tcx>])
829 -> Option<Pick<'tcx>> {
830 // Do all probes correspond to the same trait?
831 let trait_data = match probes[0].to_trait_data() {
835 if probes[1..].iter().any(|p| p.to_trait_data() != Some(trait_data)) {
839 // If so, just use this trait and call it a day.
840 let (trait_def_id, method_num) = trait_data;
841 let method_ty = probes[0].method_ty.clone();
843 method_ty: method_ty,
844 adjustment: AutoDeref(0),
845 kind: TraitPick(trait_def_id, method_num)
849 ///////////////////////////////////////////////////////////////////////////
852 fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::ures<'tcx> {
853 self.infcx().sub_types(false, infer::Misc(DUMMY_SP), sub, sup)
856 fn has_applicable_self(&self, method: &ty::Method) -> bool {
857 // "fast track" -- check for usage of sugar
858 match method.explicit_self {
859 ty::StaticExplicitSelfCategory => {
862 ty::ByValueExplicitSelfCategory |
863 ty::ByReferenceExplicitSelfCategory(..) |
864 ty::ByBoxExplicitSelfCategory => {
869 // FIXME -- check for types that deref to `Self`,
870 // like `Rc<Self>` and so on.
872 // Note also that the current code will break if this type
873 // includes any of the type parameters defined on the method
874 // -- but this could be overcome.
878 fn record_static_candidate(&mut self, source: CandidateSource) {
879 self.static_candidates.push(source);
882 fn xform_self_ty(&self,
883 method: &Rc<ty::Method<'tcx>>,
884 substs: &subst::Substs<'tcx>)
886 debug!("xform_self_ty(self_ty={}, substs={})",
887 method.fty.sig.inputs[0].repr(self.tcx()),
888 substs.repr(self.tcx()));
890 // It is possible for type parameters or early-bound lifetimes
891 // to appear in the signature of `self`. The substitutions we
892 // are given do not include type/lifetime parameters for the
893 // method yet. So create fresh variables here for those too,
895 assert_eq!(substs.types.len(subst::FnSpace), 0);
896 assert_eq!(substs.regions().len(subst::FnSpace), 0);
897 let mut substs = substs;
900 !method.generics.types.is_empty_in(subst::FnSpace) ||
901 !method.generics.regions.is_empty_in(subst::FnSpace)
904 self.infcx().next_ty_vars(
905 method.generics.types.len(subst::FnSpace));
907 // In general, during probe we erase regions. See
908 // `impl_self_ty()` for an explanation.
910 method.generics.regions.get_slice(subst::FnSpace)
912 .map(|_| ty::ReStatic)
915 placeholder = (*substs).clone().with_method(method_types, method_regions);
916 substs = &placeholder;
919 // Replace early-bound regions and types.
920 let xform_self_ty = method.fty.sig.inputs[0].subst(self.tcx(), substs);
922 // Replace late-bound regions bound in the impl or
923 // where-clause (2 levels of binding).
925 self.erase_late_bound_regions(&ty::bind(ty::bind(xform_self_ty))).value.value;
927 // Replace late-bound regions bound in the method (1 level of binding).
928 self.erase_late_bound_regions(&ty::bind(xform_self_ty)).value
931 fn impl_substs(&self,
932 impl_def_id: ast::DefId)
933 -> subst::Substs<'tcx>
935 let impl_pty = ty::lookup_item_type(self.tcx(), impl_def_id);
938 impl_pty.generics.types.map(
939 |_| self.infcx().next_ty_var());
941 let region_placeholders =
942 impl_pty.generics.regions.map(
943 |_| ty::ReStatic); // see erase_late_bound_regions() for an expl of why 'static
945 subst::Substs::new(type_vars, region_placeholders)
948 /// Replace late-bound-regions bound by `value` with `'static` using
949 /// `ty::erase_late_bound_regions`.
951 /// This is only a reasonable thing to do during the *probe* phase, not the *confirm* phase, of
952 /// method matching. It is reasonable during the probe phase because we don't consider region
953 /// relationships at all. Therefore, we can just replace all the region variables with 'static
954 /// rather than creating fresh region variables. This is nice for two reasons:
956 /// 1. Because the numbers of the region variables would otherwise be fairly unique to this
957 /// particular method call, it winds up creating fewer types overall, which helps for memory
958 /// usage. (Admittedly, this is a rather small effect, though measureable.)
960 /// 2. It makes it easier to deal with higher-ranked trait bounds, because we can replace any
961 /// late-bound regions with 'static. Otherwise, if we were going to replace late-bound
962 /// regions with actual region variables as is proper, we'd have to ensure that the same
963 /// region got replaced with the same variable, which requires a bit more coordination
964 /// and/or tracking the substitution and
966 fn erase_late_bound_regions<T>(&self, value: &T) -> T
967 where T : HigherRankedFoldable<'tcx>
969 ty::erase_late_bound_regions(self.tcx(), value)
973 fn impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
974 impl_def_id: ast::DefId,
975 method_name: ast::Name)
976 -> Option<Rc<ty::Method<'tcx>>>
978 let impl_items = tcx.impl_items.borrow();
979 let impl_items = impl_items.get(&impl_def_id).unwrap();
982 .map(|&did| ty::impl_or_trait_item(tcx, did.def_id()))
983 .find(|m| m.name() == method_name)
984 .and_then(|item| item.as_opt_method())
987 /// Find method with name `method_name` defined in `trait_def_id` and return it, along with its
988 /// index (or `None`, if no such method).
989 fn trait_method<'tcx>(tcx: &ty::ctxt<'tcx>,
990 trait_def_id: ast::DefId,
991 method_name: ast::Name)
992 -> Option<(uint, Rc<ty::Method<'tcx>>)>
994 let trait_items = ty::trait_items(tcx, trait_def_id);
998 .find(|&(_, ref item)| item.name() == method_name)
999 .and_then(|(idx, item)| item.as_opt_method().map(|m| (idx, m)))
1002 // Determine the index of a method in the list of all methods belonging
1003 // to a trait and its supertraits.
1004 fn get_method_index<'tcx>(tcx: &ty::ctxt<'tcx>,
1005 trait_ref: &ty::TraitRef<'tcx>,
1006 subtrait: Rc<ty::TraitRef<'tcx>>,
1007 n_method: uint) -> uint {
1008 // We need to figure the "real index" of the method in a
1009 // listing of all the methods of an object. We do this by
1010 // iterating down the supertraits of the object's trait until
1011 // we find the trait the method came from, counting up the
1012 // methods from them.
1013 let mut method_count = 0;
1014 ty::each_bound_trait_and_supertraits(tcx, &[subtrait], |bound_ref| {
1015 if bound_ref.def_id == trait_ref.def_id {
1018 let trait_items = ty::trait_items(tcx, bound_ref.def_id);
1019 for trait_item in trait_items.iter() {
1021 ty::MethodTraitItem(_) => method_count += 1,
1022 ty::TypeTraitItem(_) => {}
1028 method_count + n_method
1031 impl<'tcx> Candidate<'tcx> {
1032 fn to_unadjusted_pick(&self) -> Pick<'tcx> {
1034 method_ty: self.method_ty.clone(),
1035 adjustment: AutoDeref(0),
1036 kind: match self.kind {
1037 InherentImplCandidate(def_id, _) => {
1038 InherentImplPick(def_id)
1040 ObjectCandidate(ref data) => {
1041 ObjectPick(data.trait_ref.def_id, data.method_num, data.real_index)
1043 ExtensionImplCandidate(def_id, _, _, index) => {
1044 ExtensionImplPick(def_id, index)
1046 UnboxedClosureCandidate(trait_def_id, index) => {
1047 TraitPick(trait_def_id, index)
1049 WhereClauseCandidate(ref trait_ref, index) => {
1050 // Only trait derived from where-clauses should
1051 // appear here, so they should not contain any
1052 // inference variables or other artifacts. This
1053 // means they are safe to put into the
1054 // `WhereClausePick`.
1055 assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t)));
1057 WhereClausePick((*trait_ref).clone(), index)
1063 fn to_source(&self) -> CandidateSource {
1065 InherentImplCandidate(def_id, _) => ImplSource(def_id),
1066 ObjectCandidate(ref obj) => TraitSource(obj.trait_ref.def_id),
1067 ExtensionImplCandidate(def_id, _, _, _) => ImplSource(def_id),
1068 UnboxedClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id),
1069 WhereClauseCandidate(ref trait_ref, _) => TraitSource(trait_ref.def_id),
1073 fn to_trait_data(&self) -> Option<(ast::DefId,MethodIndex)> {
1075 InherentImplCandidate(..) |
1076 ObjectCandidate(..) => {
1079 UnboxedClosureCandidate(trait_def_id, method_num) => {
1080 Some((trait_def_id, method_num))
1082 ExtensionImplCandidate(_, ref trait_ref, _, method_num) |
1083 WhereClauseCandidate(ref trait_ref, method_num) => {
1084 Some((trait_ref.def_id, method_num))
1090 impl<'tcx> Repr<'tcx> for Candidate<'tcx> {
1091 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1092 format!("Candidate(xform_self_ty={}, kind={})",
1093 self.xform_self_ty.repr(tcx),
1094 self.kind.repr(tcx))
1098 impl<'tcx> Repr<'tcx> for CandidateKind<'tcx> {
1099 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1101 InherentImplCandidate(ref a, ref b) =>
1102 format!("InherentImplCandidate({},{})", a.repr(tcx), b.repr(tcx)),
1103 ObjectCandidate(ref a) =>
1104 format!("ObjectCandidate({})", a.repr(tcx)),
1105 ExtensionImplCandidate(ref a, ref b, ref c, ref d) =>
1106 format!("ExtensionImplCandidate({},{},{},{})", a.repr(tcx), b.repr(tcx),
1108 UnboxedClosureCandidate(ref a, ref b) =>
1109 format!("UnboxedClosureCandidate({},{})", a.repr(tcx), b),
1110 WhereClauseCandidate(ref a, ref b) =>
1111 format!("WhereClauseCandidate({},{})", a.repr(tcx), b),
1116 impl<'tcx> Repr<'tcx> for CandidateStep<'tcx> {
1117 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1118 format!("CandidateStep({},{})",
1119 self.self_ty.repr(tcx),
1124 impl<'tcx> Repr<'tcx> for PickAdjustment {
1125 fn repr(&self, _tcx: &ty::ctxt) -> String {
1130 impl<'tcx> Repr<'tcx> for PickKind<'tcx> {
1131 fn repr(&self, _tcx: &ty::ctxt) -> String {
1136 impl<'tcx> Repr<'tcx> for Pick<'tcx> {
1137 fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
1138 format!("Pick(method_ty={}, adjustment={}, kind={})",
1139 self.method_ty.repr(tcx),