@@ -221,7 +221,7 @@ object Signatures {
221221 val funSymbol = fun.symbol
222222 val alternatives = if funSymbol.isLocalToBlock then List (funSymbol.denot) else
223223 funSymbol.owner.info.member(funSymbol.name).alternatives
224- val alternativeIndex = alternatives.map(_.symbol).indexOf(funSymbol) max 0
224+ val alternativeIndex = bestAlternative(alternatives, params, paramssListIndex)
225225 (alternativeIndex, alternatives)
226226
227227 if alternativeIndex < alternatives.length then
@@ -660,24 +660,56 @@ object Signatures {
660660 case msg : NoMatchingOverload => msg.alternatives
661661 case _ => Nil
662662
663- val userParamsTypes = params.map(_.tpe)
664663
665664 // Assign a score to each alternative (how many parameters are correct so far), and
666665 // use that to determine what is the current active signature.
666+ val alternativeIndex = bestAlternative(alternatives, params, paramssIndex)
667+ (alternativeIndex, alternatives)
668+ }
669+
670+ /**
671+ * Given a list of alternatives, and a list of parameters, returns the index of the best
672+ * alternative, i.e. the alternative that has the most formal parameters matching the given
673+ * arguments and the least number of formal parameters.
674+ *
675+ * @param alternatives The list of alternatives to inspect.
676+ * @param params The parameters that were given at the call site.
677+ * @param paramssIndex Index of paramss we are currently in.
678+ *
679+ * @return The index of the best alternative.
680+ */
681+ private def bestAlternative (alternatives : List [SingleDenotation ], params : List [tpd.Tree ], paramssIndex : Int )(using Context ): Int =
682+ val userParamsTypes = params.map(
683+ _.tpe match
684+ case e : PreviousErrorType =>
685+ /**
686+ * In case:
687+ * def foo(i: Int, s: String): Unit = ???
688+ * def foo(i: Boolean, s: Int, x: Double): Unit = ???
689+ * foo(false, @@)
690+ *
691+ * `false` has error type: `Required: Int, Found: Boolean`
692+ */
693+ e.msg match
694+ case tm : TypeMismatch =>
695+ tm.found
696+ case _ => e
697+ case t => t
698+ )
667699 val alternativesScores = alternatives.map { alt =>
668700 val alreadyCurriedBonus = if (alt.symbol.paramSymss.length > paramssIndex) 1 else 0
669- alt.info.stripPoly match
670- case tpe : MethodType => alreadyCurriedBonus +
671- userParamsTypes.zip(tpe.paramInfos).takeWhile{ case (t0, t1) => t0 <:< t1 }.size
672- case _ => 0
701+ alt.info.stripPoly match
702+ case tpe : MethodType =>
703+ val score = alreadyCurriedBonus +
704+ userParamsTypes
705+ .zip(tpe.paramInfos)
706+ .takeWhile { case (t0, t1) => t0 <:< t1 }
707+ .size
708+ (score, - tpe.paramInfos.length)
709+ case _ => (0 , 0 )
673710 }
674-
675- val bestAlternative =
676- if (alternativesScores.isEmpty) 0
677- else alternativesScores.zipWithIndex.maxBy(_._1)._2
678-
679- (bestAlternative, alternatives)
680- }
711+ if (alternativesScores.isEmpty) 0
712+ else alternativesScores.zipWithIndex.maxBy(_._1)._2
681713}
682714
683715
0 commit comments