@@ -221,7 +221,7 @@ object Signatures {
221
221
val funSymbol = fun.symbol
222
222
val alternatives = if funSymbol.isLocalToBlock then List (funSymbol.denot) else
223
223
funSymbol.owner.info.member(funSymbol.name).alternatives
224
- val alternativeIndex = alternatives.map(_.symbol).indexOf(funSymbol) max 0
224
+ val alternativeIndex = bestAlternative(alternatives, params, paramssListIndex)
225
225
(alternativeIndex, alternatives)
226
226
227
227
if alternativeIndex < alternatives.length then
@@ -660,24 +660,56 @@ object Signatures {
660
660
case msg : NoMatchingOverload => msg.alternatives
661
661
case _ => Nil
662
662
663
- val userParamsTypes = params.map(_.tpe)
664
663
665
664
// Assign a score to each alternative (how many parameters are correct so far), and
666
665
// 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
+ )
667
699
val alternativesScores = alternatives.map { alt =>
668
700
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 )
673
710
}
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
681
713
}
682
714
683
715
0 commit comments