@@ -645,6 +645,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
645645 }
646646
647647 let mut candidates = candidate_set. vec ;
648+ let candidate;
648649
649650 debug ! ( "assembled {} candidates for {}: {}" ,
650651 candidates. len( ) ,
@@ -678,39 +679,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
678679 candidates. retain ( |c| self . winnow_candidate ( stack, c) . may_apply ( ) )
679680 }
680681
681- // If the predicate is fully known, there should be only one
682- // matching candidate by coherence. However, there may also be
683- // other candidates from impls (see the doc-comment for
684- // Candidate). Pick one candidate to use. This is somewhat
685- // wrong around regions.
686- if candidates. len ( ) > 1 && !stack. obligation . predicate . has_ty_infer ( ) {
687- let mut i = 0 ;
688- while i < candidates. len ( ) {
689- let is_dup =
690- ( 0 ..candidates. len ( ) )
691- . filter ( |& j| i != j)
692- . any ( |j| self . candidate_should_be_dropped_in_favor_of ( & candidates[ i] ,
693- & candidates[ j] ) ) ;
694- if is_dup {
695- debug ! ( "Dropping candidate #{}/{}: {}" ,
696- i, candidates. len( ) , candidates[ i] . repr( self . tcx( ) ) ) ;
697- candidates. swap_remove ( i) ;
698- } else {
699- debug ! ( "Retaining candidate #{}/{}: {}" ,
700- i, candidates. len( ) , candidates[ i] . repr( self . tcx( ) ) ) ;
701- i += 1 ;
702- }
703- }
704- }
705-
706- // If there are *STILL* multiple candidates, give up and
707- // report ambiguity.
708- if candidates. len ( ) > 1 {
709- debug ! ( "multiple matches, ambig" ) ;
710- return Ok ( None ) ;
711- }
712-
713-
714682 // If there are *NO* candidates, that there are no impls --
715683 // that we know of, anyway. Note that in the case where there
716684 // are unbound type variables within the obligation, it might
@@ -724,22 +692,65 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
724692 return Err ( Unimplemented ) ;
725693 }
726694
727- // Just one candidate left.
728- let candidate = candidates. pop ( ) . unwrap ( ) ;
729-
730- match candidate {
731- ImplCandidate ( def_id) => {
732- match ty:: trait_impl_polarity ( self . tcx ( ) , def_id) {
733- Some ( ast:: ImplPolarity :: Negative ) => return Err ( Unimplemented ) ,
734- _ => { }
695+ let candidate;
696+ if let Some ( c) = self . find_sure_clause ( & stack. obligation , & candidates) {
697+ // If we have a projection/where-clause candidate that
698+ // surely matches, go ahead and pick it. There can be other
699+ // candidates that match, but the clause will transform into
700+ // the right one at monomorphization-time.
701+ candidate = candidates. swap_remove ( c)
702+ } else {
703+ candidate = candidates. pop ( ) . unwrap ( ) ;
704+
705+ // If there are *still* multiple distinct candidates,
706+ // report ambiguity.
707+ for c in candidates {
708+ if c != candidate {
709+ debug ! ( "multiple matches, ambig" ) ;
710+ return Ok ( None ) ;
735711 }
736712 }
737- _ => { }
713+ }
714+
715+ if let ImplCandidate ( def_id) = candidate {
716+ let polarity = ty:: trait_impl_polarity ( self . tcx ( ) , def_id) ;
717+ if polarity == Some ( ast:: ImplPolarity :: Negative ) {
718+ return Err ( Unimplemented ) ;
719+ }
738720 }
739721
740722 Ok ( Some ( candidate) )
741723 }
742724
725+ /// Return the index of a where clause/projection that surely matches out
726+ /// of cs, if any exists.
727+ ///
728+ /// This is somewhat wrong as it does not take regions into account.
729+ fn find_sure_candidate( & self ,
730+ obligation : & TraitObligation < ' tcx > ,
731+ cs : & [ SelectionCandidate < ' tcx > ] )
732+ -> Option < usize >
733+ {
734+ let sure_projection = None ;
735+ let sure_impl = None ;
736+ for ( i, candidate) in cs. iter ( ) . enumerate ( ) {
737+ match candidate {
738+ & ErrorCandidate => return None ,
739+ & ProjectionCandidate => {
740+ // if let Ok(_) = self.match_where_
741+ } ,
742+ & ImplCandidate ( iid) => {
743+ if let Ok ( ..) = self . infcx . can_equate (
744+ & obligation. predicate . trait_ref . 0 ,
745+ &
746+ } ,
747+ _ => { }
748+ }
749+ }
750+
751+ sure_projection. or ( sure_impl)
752+ }
753+
743754 fn pick_candidate_cache ( & self ) -> & SelectionCache <' tcx> {
744755 // If there are any where-clauses in scope, then we always use
745756 // a cache local to this particular scope. Otherwise, we
0 commit comments