private Binding selectCallableCandidate ( Name name , List < Binding > candidates , LifetimeRelation lifetimes ) { Binding best = null ; Type . Callable bestType = null ; boolean bestValidWinner = false ; // for ( int i = 0 ; i != candidates . size ( ) ; ++ i ) { Binding candidate = candidates . get ( i ) ; Type . Callable candidateType = candidate . getConcreteType ( ) ; if ( best == null ) { // No other candidates are applicable so far. Hence, this // one is automatically promoted to the best seen so far. best = candidate ; bestType = candidateType ; bestValidWinner = true ; } else { boolean csubb = isSubtype ( bestType , candidateType , lifetimes ) ; boolean bsubc = isSubtype ( candidateType , bestType , lifetimes ) ; // if ( csubb && ! bsubc ) { // This candidate is a subtype of the best seen so far. Hence, it is now the // best seen so far. best = candidate ; bestType = candidate . getConcreteType ( ) ; bestValidWinner = true ; } else if ( bsubc && ! csubb ) { // This best so far is a subtype of this candidate. Therefore, we can simply // discard this candidate from consideration since it's definitely not the best. } else if ( ! csubb && ! bsubc ) { // This is the awkward case. Neither the best so far, nor the candidate, are // subtypes of each other. In this case, we report an error. NOTE: must perform // an explicit equality check above due to the present of type invariants. // Specifically, without this check, the system will treat two declarations with // identical raw types (though non-identical actual types) as the same. return null ; } else { // This is a tricky case. We have two types after instantiation which are // considered identical under the raw subtype test. As such, they may not be // actually identical (e.g. if one has a type invariant). Furthermore, we cannot // stop at this stage as, in principle, we could still find an outright winner. bestValidWinner = false ; } } } return bestValidWinner ? best : null ; }
Given a list of candidate function or method declarations determine the most precise match for the supplied argument types . The given argument types must be applicable to this function or macro declaration and it must be a subtype of all other applicable candidates .