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 /*! See `doc.rs` for high-level documentation */
13 use super::{Obligation, ObligationCause};
14 use super::{EvaluationResult, EvaluatedToMatch,
15 EvaluatedToAmbiguity, EvaluatedToUnmatch};
16 use super::{SelectionError, Unimplemented, Overflow,
17 OutputTypeParameterMismatch};
18 use super::{Selection};
19 use super::{SelectionResult};
20 use super::{VtableBuiltin, VtableImpl, VtableParam, VtableUnboxedClosure};
21 use super::{VtableImplData, VtableParamData};
24 use middle::subst::{Subst, Substs, VecPerParamSpace};
26 use middle::typeck::check::regionmanip;
27 use middle::typeck::infer;
28 use middle::typeck::infer::InferCtxt;
31 use util::nodemap::DefIdMap;
32 use util::ppaux::Repr;
34 pub struct SelectionContext<'cx, 'tcx:'cx> {
35 infcx: &'cx InferCtxt<'cx, 'tcx>,
36 param_env: &'cx ty::ParameterEnvironment,
37 unboxed_closures: &'cx DefIdMap<ty::UnboxedClosure>,
40 // pub struct SelectionCache {
41 // hashmap: RefCell<HashMap<CacheKey, Candidate>>,
44 // #[deriving(Hash,Eq,PartialEq)]
46 // trait_def_id: ast::DefId,
47 // skol_obligation_self_ty: ty::t,
57 * The selection process begins by considering all impls, where
58 * clauses, and so forth that might resolve an obligation. Sometimes
59 * we'll be able to say definitively that (e.g.) an impl does not
60 * apply to the obligation: perhaps it is defined for `uint` but the
61 * obligation is for `int`. In that case, we drop the impl out of the
62 * list. But the other cases are considered *candidates*.
64 * Candidates can either be definitive or ambiguous. An ambiguous
65 * candidate is one that might match or might not, depending on how
66 * type variables wind up being resolved. This only occurs during inference.
68 * For selection to suceed, there must be exactly one non-ambiguous
69 * candidate. Usually, it is not possible to have more than one
70 * definitive candidate, due to the coherence rules. However, there is
71 * one case where it could occur: if there is a blanket impl for a
72 * trait (that is, an impl applied to all T), and a type parameter
73 * with a where clause. In that case, we can have a candidate from the
74 * where clause and a second candidate from the impl. This is not a
75 * problem because coherence guarantees us that the impl which would
76 * be used to satisfy the where clause is the same one that we see
77 * now. To resolve this issue, therefore, we ignore impls if we find a
78 * matching where clause. Part of the reason for this is that where
79 * clauses can give additional information (like, the types of output
80 * parameters) that would have to be inferred from the impl.
84 MatchedBuiltinCandidate,
85 AmbiguousBuiltinCandidate,
86 MatchedParamCandidate(VtableParamData),
87 AmbiguousParamCandidate,
89 MatchedUnboxedClosureCandidate(/* closure */ ast::DefId)
94 MatchedImplCandidate(ast::DefId),
95 AmbiguousImplCandidate(ast::DefId),
98 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
99 pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
100 param_env: &'cx ty::ParameterEnvironment,
101 unboxed_closures: &'cx DefIdMap<ty::UnboxedClosure>)
102 -> SelectionContext<'cx, 'tcx> {
103 SelectionContext { infcx: infcx, param_env: param_env,
104 unboxed_closures: unboxed_closures }
107 pub fn tcx(&self) -> &'cx ty::ctxt<'tcx> {
111 ///////////////////////////////////////////////////////////////////////////
114 // The selection phase tries to identify *how* an obligation will
115 // be resolved. For example, it will identify which impl or
116 // parameter bound is to be used. The process can be inconclusive
117 // if the self type in the obligation is not fully inferred. Selection
118 // can result in an error in one of two ways:
120 // 1. If no applicable impl or parameter bound can be found.
121 // 2. If the output type parameters in the obligation do not match
122 // those specified by the impl/bound. For example, if the obligation
123 // is `Vec<Foo>:Iterable<Bar>`, but the impl specifies
124 // `impl<T> Iterable<T> for Vec<T>`, than an error would result.
126 pub fn select(&self, obligation: &Obligation) -> SelectionResult<Selection> {
128 * Evaluates whether the obligation can be satisfied. Returns
129 * an indication of whether the obligation can be satisfied
130 * and, if so, by what means. Never affects surrounding typing
134 debug!("select({})", obligation.repr(self.tcx()));
136 match try!(self.candidate_from_obligation(obligation)) {
138 Some(candidate) => self.confirm_candidate(obligation, candidate),
142 pub fn select_inherent_impl(&self,
143 impl_def_id: ast::DefId,
144 obligation_cause: ObligationCause,
145 obligation_self_ty: ty::t)
146 -> SelectionResult<VtableImplData<Obligation>>
148 debug!("select_inherent_impl(impl_def_id={}, obligation_self_ty={})",
149 impl_def_id.repr(self.tcx()),
150 obligation_self_ty.repr(self.tcx()));
152 match self.candidate_from_impl(impl_def_id,
154 obligation_self_ty) {
155 Some(MatchedImplCandidate(impl_def_id)) => {
157 try!(self.confirm_inherent_impl_candidate(
162 Ok(Some(vtable_impl))
164 Some(AmbiguousImplCandidate(_)) => {
173 ///////////////////////////////////////////////////////////////////////////
176 // Tests whether an obligation can be selected or whether an impl can be
177 // applied to particular types. It skips the "confirmation" step and
178 // hence completely ignores output type parameters.
180 pub fn evaluate_obligation(&self,
181 obligation: &Obligation)
185 * Evaluates whether the obligation `obligation` can be
186 * satisfied (by any means).
189 debug!("evaluate_obligation({})",
190 obligation.repr(self.tcx()));
192 match self.candidate_from_obligation(obligation) {
193 Ok(Some(c)) => c.to_evaluation_result(),
194 Ok(None) => EvaluatedToAmbiguity,
195 Err(_) => EvaluatedToUnmatch,
199 pub fn evaluate_impl(&self,
200 impl_def_id: ast::DefId,
201 obligation_cause: ObligationCause,
202 obligation_self_ty: ty::t)
206 * Evaluates whether the impl with id `impl_def_id` could be
207 * applied to the self type `obligation_self_ty`. This can be
208 * used either for trait or inherent impls.
211 debug!("evaluate_impl(impl_def_id={}, obligation_self_ty={})",
212 impl_def_id.repr(self.tcx()),
213 obligation_self_ty.repr(self.tcx()));
215 match self.candidate_from_impl(impl_def_id,
217 obligation_self_ty) {
218 Some(c) => c.to_evaluation_result(),
219 None => EvaluatedToUnmatch,
223 ///////////////////////////////////////////////////////////////////////////
224 // CANDIDATE ASSEMBLY
226 // The selection process begins by examining all in-scope impls,
227 // caller obligations, and so forth and assembling a list of
228 // candidates. See `doc.rs` and the `Candidate` type for more details.
230 fn candidate_from_obligation(&self, obligation: &Obligation)
231 -> SelectionResult<Candidate>
233 debug!("candidate_from_obligation({}, self_ty={})",
234 obligation.repr(self.tcx()),
235 self.infcx.ty_to_string(obligation.self_ty()));
237 let skol_obligation_self_ty =
238 infer::skolemize(self.infcx, obligation.self_ty());
240 // First, check the cache.
241 match self.check_candidate_cache(obligation, skol_obligation_self_ty) {
249 try!(self.assemble_candidates(obligation,
250 skol_obligation_self_ty));
252 debug!("candidate_from_obligation: {} candidates for {}",
253 candidates.len(), obligation.repr(self.tcx()));
255 // Examine candidates to determine outcome. Ideally we will
256 // have exactly one candidate that is definitively applicable.
258 if candidates.len() == 0 {
259 // Annoying edge case: if there are no impls, then there
260 // is no way that this trait reference is implemented,
261 // *unless* it contains unbound variables. In that case,
262 // it is possible that one of those unbound variables will
263 // be bound to a new type from some other crate which will
264 // also contain impls.
265 let trait_ref = &*obligation.trait_ref;
266 return if !self.trait_ref_unconstrained(trait_ref) {
267 debug!("candidate_from_obligation({}) -> 0 matches, unimpl",
268 obligation.repr(self.tcx()));
271 debug!("candidate_from_obligation({}) -> 0 matches, ambig",
272 obligation.repr(self.tcx()));
277 if candidates.len() > 1 {
278 // Ambiguity. Possibly we should report back more
279 // information on the potential candidates so we can give
280 // a better error message.
281 debug!("candidate_from_obligation({}) -> multiple matches, ambig",
282 obligation.repr(self.tcx()));
287 let candidate = candidates.pop().unwrap();
288 self.insert_candidate_cache(obligation, skol_obligation_self_ty,
293 fn check_candidate_cache(&self,
294 _obligation: &Obligation,
295 _skol_obligation_self_ty: ty::t)
298 // let cache_key = CacheKey::new(obligation.trait_ref.def_id,
299 // skol_obligation_self_ty);
300 // let hashmap = self.tcx().selection_cache.hashmap.borrow();
301 // hashmap.find(&cache_key).map(|c| (*c).clone())
305 fn insert_candidate_cache(&self,
306 _obligation: &Obligation,
307 _skol_obligation_self_ty: ty::t,
308 _candidate: Candidate)
310 // FIXME -- Enable caching. I think the right place to put the cache
311 // is in the ParameterEnvironment, not the tcx, because otherwise
312 // when there are distinct where clauses in scope the cache can get
315 //let cache_key = CacheKey::new(obligation.trait_ref.def_id,
316 // skol_obligation_self_ty);
317 //let mut hashmap = self.tcx().selection_cache.hashmap.borrow_mut();
318 //hashmap.insert(cache_key, candidate);
321 fn assemble_candidates(&self,
322 obligation: &Obligation,
323 skol_obligation_self_ty: ty::t)
324 -> Result<Vec<Candidate>, SelectionError>
326 // Check for overflow.
328 let recursion_limit = self.infcx.tcx.sess.recursion_limit.get();
329 if obligation.recursion_depth >= recursion_limit {
330 debug!("{} --> overflow", obligation.repr(self.tcx()));
331 return Err(Overflow);
334 let mut candidates = Vec::new();
336 match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.def_id) {
338 // FIXME -- The treatment of builtin bounds is a bit
339 // hacky right now. Eventually, the idea is to move
340 // the logic for selection out of type_contents and
341 // into this module (And make it based on the generic
342 // mechanisms of OIBTT2). However, I want to land
343 // some code today, so we're going to cut a few
344 // corners. What we do now is that the trait selection
345 // code always considers builtin obligations to
346 // match. The fulfillment code (which also has the job
347 // of tracking all the traits that must hold) will
348 // then just accumulate the various
349 // builtin-bound-related obligations that must be met.
350 // Later, at the end of typeck, after writeback etc,
351 // we will rewalk this list and extract all the
352 // builtin-bound-related obligations and test them
353 // again using type contents. Part of the motivation
354 // for this is that the type contents code requires
355 // that writeback has been completed in some cases.
357 candidates.push(AmbiguousBuiltinCandidate);
361 // Other bounds. Consider both in-scope bounds from fn decl
362 // and applicable impls.
364 try!(self.assemble_candidates_from_caller_bounds(
366 skol_obligation_self_ty,
369 try!(self.assemble_unboxed_candidates(
371 skol_obligation_self_ty,
374 // If there is a fn bound that applies, forego the
375 // impl search. It can only generate conflicts.
377 if candidates.len() == 0 {
378 try!(self.assemble_candidates_from_impls(
380 skol_obligation_self_ty,
389 fn assemble_candidates_from_caller_bounds(&self,
390 obligation: &Obligation,
391 skol_obligation_self_ty: ty::t,
392 candidates: &mut Vec<Candidate>)
393 -> Result<(),SelectionError>
396 * Given an obligation like `<SomeTrait for T>`, search the obligations
397 * that the caller supplied to find out whether it is listed among
400 * Never affects inference environment.
403 debug!("assemble_candidates_from_caller_bounds({})",
404 obligation.repr(self.tcx()));
406 for caller_obligation in self.param_env.caller_obligations.iter() {
407 debug!("caller_obligation={}",
408 caller_obligation.repr(self.tcx()));
410 // Skip over obligations that don't apply to
412 let caller_bound = &caller_obligation.trait_ref;
413 let caller_self_ty = caller_bound.substs.self_ty().unwrap();
414 match self.match_self_types(obligation.cause,
416 skol_obligation_self_ty) {
418 debug!("-> AmbiguousParamCandidate");
419 candidates.push(AmbiguousParamCandidate);
428 // Search through the trait (and its supertraits) to
429 // see if it matches the def-id we are looking for.
430 let caller_bound = (*caller_bound).clone();
431 match util::search_trait_and_supertraits_from_bound(
432 self.infcx.tcx, caller_bound,
433 |d| d == obligation.trait_ref.def_id)
435 Some(vtable_param) => {
436 // If so, we're done!
437 debug!("-> MatchedParamCandidate({})", vtable_param);
438 candidates.push(MatchedParamCandidate(vtable_param));
450 fn assemble_unboxed_candidates(&self,
451 obligation: &Obligation,
452 skol_obligation_self_ty: ty::t,
453 candidates: &mut Vec<Candidate>)
454 -> Result<(),SelectionError>
457 * Check for the artificial impl that the compiler will create
458 * for an obligation like `X : FnMut<..>` where `X` is an
459 * unboxed closure type.
462 let closure_def_id = match ty::get(skol_obligation_self_ty).sty {
463 ty::ty_unboxed_closure(id, _) => id,
464 _ => { return Ok(()); }
467 let tcx = self.tcx();
469 (ty::FnUnboxedClosureKind, tcx.lang_items.fn_trait()),
470 (ty::FnMutUnboxedClosureKind, tcx.lang_items.fn_mut_trait()),
471 (ty::FnOnceUnboxedClosureKind, tcx.lang_items.fn_once_trait()),
473 for tuple in fn_traits.iter() {
474 let kind = match tuple {
475 &(kind, Some(ref fn_trait))
476 if *fn_trait == obligation.trait_ref.def_id =>
483 // Check to see whether the argument and return types match.
484 let closure_kind = match self.unboxed_closures.find(&closure_def_id) {
485 Some(closure) => closure.kind,
487 self.tcx().sess.span_bug(
488 obligation.cause.span,
489 format!("No entry for unboxed closure: {}",
490 closure_def_id.repr(self.tcx())).as_slice());
494 if closure_kind != kind {
498 candidates.push(MatchedUnboxedClosureCandidate(closure_def_id));
504 fn assemble_candidates_from_impls(&self,
505 obligation: &Obligation,
506 skol_obligation_self_ty: ty::t,
507 candidates: &mut Vec<Candidate>)
508 -> Result<(), SelectionError>
511 * Search for impls that might apply to `obligation`.
514 let all_impls = self.all_impls(obligation.trait_ref.def_id);
515 for &impl_def_id in all_impls.iter() {
516 self.infcx.probe(|| {
517 match self.candidate_from_impl(impl_def_id,
519 skol_obligation_self_ty) {
521 candidates.push(Impl(c));
531 fn candidate_from_impl(&self,
532 impl_def_id: ast::DefId,
533 obligation_cause: ObligationCause,
534 skol_obligation_self_ty: ty::t)
535 -> Option<ImplCandidate>
537 match self.match_impl_self_types(impl_def_id,
539 skol_obligation_self_ty) {
541 Some(MatchedImplCandidate(impl_def_id))
545 Some(AmbiguousImplCandidate(impl_def_id))
554 ///////////////////////////////////////////////////////////////////////////
557 // Confirmation unifies the output type parameters of the trait
558 // with the values found in the obligation, possibly yielding a
559 // type error. See `doc.rs` for more details.
561 fn confirm_candidate(&self,
562 obligation: &Obligation,
563 candidate: Candidate)
564 -> SelectionResult<Selection>
566 debug!("confirm_candidate({}, {})",
567 obligation.repr(self.tcx()),
568 candidate.repr(self.tcx()));
571 AmbiguousBuiltinCandidate |
572 AmbiguousParamCandidate |
573 Impl(AmbiguousImplCandidate(_)) => {
577 MatchedBuiltinCandidate => {
578 Ok(Some(VtableBuiltin))
581 MatchedParamCandidate(param) => {
583 try!(self.confirm_param_candidate(obligation, param)))))
586 Impl(MatchedImplCandidate(impl_def_id)) => {
587 let vtable_impl = try!(self.confirm_impl_candidate(obligation,
589 Ok(Some(VtableImpl(vtable_impl)))
592 MatchedUnboxedClosureCandidate(closure_def_id) => {
593 try!(self.confirm_unboxed_closure_candidate(obligation, closure_def_id));
594 Ok(Some(VtableUnboxedClosure(closure_def_id)))
599 fn confirm_param_candidate(&self,
600 obligation: &Obligation,
601 param: VtableParamData)
602 -> Result<VtableParamData,SelectionError>
604 debug!("confirm_param_candidate({},{})",
605 obligation.repr(self.tcx()),
606 param.repr(self.tcx()));
608 let () = try!(self.confirm(obligation.cause,
609 obligation.trait_ref.clone(),
610 param.bound.clone()));
614 fn confirm_impl_candidate(&self,
615 obligation: &Obligation,
616 impl_def_id: ast::DefId)
617 -> Result<VtableImplData<Obligation>,SelectionError>
619 debug!("confirm_impl_candidate({},{})",
620 obligation.repr(self.tcx()),
621 impl_def_id.repr(self.tcx()));
623 // For a non-inhernet impl, we begin the same way as an
624 // inherent impl, by matching the self-type and assembling
625 // list of nested obligations.
627 try!(self.confirm_inherent_impl_candidate(
630 obligation.trait_ref.self_ty(),
631 obligation.recursion_depth));
633 // But then we must also match the output types.
634 let () = try!(self.confirm_impl_vtable(impl_def_id,
636 obligation.trait_ref.clone(),
637 &vtable_impl.substs));
641 fn confirm_inherent_impl_candidate(&self,
642 impl_def_id: ast::DefId,
643 obligation_cause: ObligationCause,
644 obligation_self_ty: ty::t,
645 obligation_recursion_depth: uint)
646 -> Result<VtableImplData<Obligation>,
649 let substs = match self.match_impl_self_types(impl_def_id,
651 obligation_self_ty) {
652 Matched(substs) => substs,
653 AmbiguousMatch | NoMatch => {
655 format!("Impl {} was matchable against {} but now is not",
656 impl_def_id.repr(self.tcx()),
657 obligation_self_ty.repr(self.tcx()))
662 let impl_obligations =
663 self.impl_obligations(obligation_cause,
664 obligation_recursion_depth,
667 let vtable_impl = VtableImplData { impl_def_id: impl_def_id,
669 nested: impl_obligations };
674 fn confirm_unboxed_closure_candidate(&self,
675 obligation: &Obligation,
676 closure_def_id: ast::DefId)
677 -> Result<(),SelectionError>
679 debug!("confirm_unboxed_closure_candidate({},{})",
680 obligation.repr(self.tcx()),
681 closure_def_id.repr(self.tcx()));
683 let closure_type = match self.unboxed_closures.find(&closure_def_id) {
684 Some(closure) => closure.closure_type.clone(),
686 self.tcx().sess.span_bug(
687 obligation.cause.span,
688 format!("No entry for unboxed closure: {}",
689 closure_def_id.repr(self.tcx())).as_slice());
693 // FIXME(pcwalton): This is a bogus thing to do, but
694 // it'll do for now until we get the new trait-bound
695 // region skolemization working.
696 let (_, new_signature) =
697 regionmanip::replace_late_bound_regions_in_fn_sig(
700 |br| self.infcx.next_region_var(
701 infer::LateBoundRegion(obligation.cause.span, br)));
703 let arguments_tuple = *new_signature.inputs.get(0);
704 let trait_ref = Rc::new(ty::TraitRef {
705 def_id: obligation.trait_ref.def_id,
706 substs: Substs::new_trait(
707 vec![arguments_tuple, new_signature.output],
709 obligation.self_ty())
712 self.confirm(obligation.cause,
713 obligation.trait_ref.clone(),
717 ///////////////////////////////////////////////////////////////////////////
720 // Matching is a common path used for both evaluation and
721 // confirmation. It basically unifies types that appear in impls
722 // and traits. This does affect the surrounding environment;
723 // therefore, when used during evaluation, match routines must be
724 // run inside of a `probe()` so that their side-effects are
727 fn match_impl_self_types(&self,
728 impl_def_id: ast::DefId,
729 obligation_cause: ObligationCause,
730 obligation_self_ty: ty::t)
731 -> MatchResult<Substs>
734 * Determines whether the self type declared against
735 * `impl_def_id` matches `obligation_self_ty`. If successful,
736 * returns the substitutions used to make them match. See
737 * `match_impl()`. For example, if `impl_def_id` is declared
740 * impl<T:Copy> Foo for ~T { ... }
742 * and `obligation_self_ty` is `int`, we'd back an `Err(_)`
743 * result. But if `obligation_self_ty` were `~int`, we'd get
747 // Create fresh type variables for each type parameter declared
749 let impl_substs = util::fresh_substs_for_impl(self.infcx,
750 obligation_cause.span,
753 // Find the self type for the impl.
754 let impl_self_ty = ty::lookup_item_type(self.tcx(), impl_def_id).ty;
755 let impl_self_ty = impl_self_ty.subst(self.tcx(), &impl_substs);
757 debug!("match_impl_self_types(obligation_self_ty={}, impl_self_ty={})",
758 obligation_self_ty.repr(self.tcx()),
759 impl_self_ty.repr(self.tcx()));
761 match self.match_self_types(obligation_cause,
763 obligation_self_ty) {
765 debug!("Matched impl_substs={}", impl_substs.repr(self.tcx()));
769 debug!("AmbiguousMatch");
779 fn match_self_types(&self,
780 cause: ObligationCause,
782 // The self type provided by the impl/caller-obligation:
783 provided_self_ty: ty::t,
785 // The self type the obligation is for:
786 required_self_ty: ty::t)
789 // FIXME(#5781) -- equating the types is stronger than
790 // necessary. Should consider variance of trait w/r/t Self.
792 let origin = infer::RelateSelfType(cause.span);
793 match self.infcx.eq_types(false,
797 Ok(()) => Matched(()),
798 Err(ty::terr_sorts(ty::expected_found{expected: t1, found: t2})) => {
799 // This error occurs when there is an unresolved type
800 // variable in the `required_self_ty` that was forced
801 // to unify with a non-type-variable. That basically
802 // means we don't know enough to say with certainty
803 // whether there is a match or not -- it depends on
804 // how that type variable is ultimately resolved.
805 if ty::type_is_skolemized(t1) || ty::type_is_skolemized(t2) {
815 ///////////////////////////////////////////////////////////////////////////
818 // The final step of selection: once we know how an obligation is
819 // is resolved, we confirm that selection in order to have
820 // side-effects on the typing environment. This step also unifies
821 // the output type parameters from the obligation with those found
822 // on the impl/bound, which may yield type errors.
824 fn confirm_impl_vtable(&self,
825 impl_def_id: ast::DefId,
826 obligation_cause: ObligationCause,
827 obligation_trait_ref: Rc<ty::TraitRef>,
829 -> Result<(), SelectionError>
832 * Relates the output type parameters from an impl to the
833 * trait. This may lead to type errors. The confirmation step
834 * is separated from the main match procedure because these
835 * type errors do not cause us to select another impl.
837 * As an example, consider matching the obligation
838 * `Iterator<char> for Elems<int>` using the following impl:
840 * impl<T> Iterator<T> for Elems<T> { ... }
842 * The match phase will succeed with substitution `T=int`.
843 * The confirm step will then try to unify `int` and `char`
844 * and yield an error.
847 let impl_trait_ref = ty::impl_trait_ref(self.tcx(),
848 impl_def_id).unwrap();
849 let impl_trait_ref = impl_trait_ref.subst(self.tcx(),
851 self.confirm(obligation_cause, obligation_trait_ref, impl_trait_ref)
855 obligation_cause: ObligationCause,
856 obligation_trait_ref: Rc<ty::TraitRef>,
857 expected_trait_ref: Rc<ty::TraitRef>)
858 -> Result<(), SelectionError>
861 * After we have determined which impl applies, and with what
862 * substitutions, there is one last step. We have to go back
863 * and relate the "output" type parameters from the obligation
864 * to the types that are specified in the impl.
866 * For example, imagine we have:
868 * impl<T> Iterator<T> for Vec<T> { ... }
870 * and our obligation is `Iterator<Foo> for Vec<int>` (note
871 * the mismatch in the obligation types). Up until this step,
872 * no error would be reported: the self type is `Vec<int>`,
873 * and that matches `Vec<T>` with the substitution `T=int`.
874 * At this stage, we could then go and check that the type
875 * parameters to the `Iterator` trait match.
876 * (In terms of the parameters, the `expected_trait_ref`
877 * here would be `Iterator<int> for Vec<int>`, and the
878 * `obligation_trait_ref` would be `Iterator<Foo> for Vec<int>`.
880 * Note that this checking occurs *after* the impl has
881 * selected, because these output type parameters should not
882 * affect the selection of the impl. Therefore, if there is a
883 * mismatch, we report an error to the user.
886 let origin = infer::RelateOutputImplTypes(obligation_cause.span);
888 let obligation_trait_ref = obligation_trait_ref.clone();
889 match self.infcx.sub_trait_refs(false,
891 expected_trait_ref.clone(),
892 obligation_trait_ref) {
894 Err(e) => Err(OutputTypeParameterMismatch(expected_trait_ref, e))
898 ///////////////////////////////////////////////////////////////////////////
901 fn all_impls(&self, trait_def_id: ast::DefId) -> Vec<ast::DefId> {
903 * Returns se tof all impls for a given trait.
906 ty::populate_implementations_for_trait_if_necessary(self.tcx(),
908 match self.tcx().trait_impls.borrow().find(&trait_def_id) {
910 Some(impls) => impls.borrow().clone()
914 fn impl_obligations(&self,
915 cause: ObligationCause,
916 recursion_depth: uint,
917 impl_def_id: ast::DefId,
918 impl_substs: &Substs)
919 -> VecPerParamSpace<Obligation>
921 let impl_generics = ty::lookup_item_type(self.tcx(),
922 impl_def_id).generics;
923 util::obligations_for_generics(self.tcx(), cause, recursion_depth,
924 &impl_generics, impl_substs)
927 fn trait_ref_unconstrained(&self,
928 trait_ref: &ty::TraitRef)
932 * True if the self type of the trait-ref contains
933 * unconstrained type variables.
936 let mut found_skol = false;
938 // Skolemization replaces all unconstrained type vars with
939 // a SkolemizedTy instance. Then we search to see if we
941 let skol_ty = infer::skolemize(self.infcx, trait_ref.self_ty());
942 ty::walk_ty(skol_ty, |t| {
943 match ty::get(t).sty {
944 ty::ty_infer(ty::SkolemizedTy(_)) => { found_skol = true; }
954 fn to_evaluation_result(&self) -> EvaluationResult {
956 Impl(ref i) => i.to_evaluation_result(),
958 MatchedUnboxedClosureCandidate(..) |
959 MatchedBuiltinCandidate |
960 MatchedParamCandidate(..) => {
964 AmbiguousBuiltinCandidate |
965 AmbiguousParamCandidate => {
973 fn to_evaluation_result(&self) -> EvaluationResult {
975 MatchedImplCandidate(..) => EvaluatedToMatch,
976 AmbiguousImplCandidate(..) => EvaluatedToAmbiguity
981 impl Repr for Candidate {
982 fn repr(&self, tcx: &ty::ctxt) -> String {
984 MatchedBuiltinCandidate => format!("MatchedBuiltinCandidate"),
985 AmbiguousBuiltinCandidate => format!("AmbiguousBuiltinCandidate"),
986 MatchedUnboxedClosureCandidate(c) => format!("MatchedUnboxedClosureCandidate({})", c),
987 MatchedParamCandidate(ref r) => format!("MatchedParamCandidate({})",
989 AmbiguousParamCandidate => format!("AmbiguousParamCandidate"),
990 Impl(ref i) => i.repr(tcx)
995 impl Repr for ImplCandidate {
996 fn repr(&self, tcx: &ty::ctxt) -> String {
998 MatchedImplCandidate(ref d) => format!("MatchedImplCandidate({})",
1000 AmbiguousImplCandidate(ref d) => format!("AmbiguousImplCandidate({})",
1007 // impl SelectionCache {
1008 // pub fn new() -> SelectionCache {
1010 // hashmap: RefCell::new(HashMap::new())
1016 // pub fn new(trait_def_id: ast::DefId,
1017 // skol_obligation_self_ty: ty::t)
1021 // trait_def_id: trait_def_id,
1022 // skol_obligation_self_ty: skol_obligation_self_ty