@@ -1733,8 +1733,6 @@ trait Applications extends Compatibility {
17331733 def compare (alt1 : TermRef , alt2 : TermRef , preferGeneral : Boolean = false )(using Context ): Int = trace(i " compare( $alt1, $alt2) " , overload) {
17341734 record(" resolveOverloaded.compare" )
17351735
1736- val compareGivens = alt1.symbol.is(Given ) && alt2.symbol.is(Given )
1737-
17381736 /** Is alternative `alt1` with type `tp1` as good as alternative
17391737 * `alt2` with type `tp2` ?
17401738 *
@@ -1749,7 +1747,7 @@ trait Applications extends Compatibility {
17491747 * from below by Li and from above by Ui.
17501748 * 3. A member of any other type `tp1` is:
17511749 * a. always as good as a method or a polymorphic method.
1752- * b. as good as a member of any other type `tp2` is `asGoodValueType(tp1, tp2) = true`
1750+ * b. as good as a member of any other type `tp2` if `asGoodValueType(tp1, tp2) = true`
17531751 */
17541752 def isAsGood (alt1 : TermRef , tp1 : Type , alt2 : TermRef , tp2 : Type ): Boolean = trace(i " isAsSpecific $tp1 $tp2" , overload) {
17551753 tp1 match
@@ -1776,13 +1774,17 @@ trait Applications extends Compatibility {
17761774 isAsGood(alt1, tp1.instantiate(tparams.map(_.typeRef)), alt2, tp2)
17771775 }
17781776 case _ => // (3)
1777+ def isGiven (alt : TermRef ) =
1778+ alt1.symbol.is(Given ) && alt.symbol != defn.NotGivenClass
1779+ def compareValues (tp1 : Type , tp2 : Type )(using Context ) =
1780+ isAsGoodValueType(tp1, tp2, isGiven(alt1), isGiven(alt2))
17791781 tp2 match
17801782 case tp2 : MethodType => true // (3a)
17811783 case tp2 : PolyType if tp2.resultType.isInstanceOf [MethodType ] => true // (3a)
17821784 case tp2 : PolyType => // (3b)
1783- explore(isAsGoodValueType (tp1, instantiateWithTypeVars(tp2)))
1785+ explore(compareValues (tp1, instantiateWithTypeVars(tp2)))
17841786 case _ => // 3b)
1785- isAsGoodValueType (tp1, tp2)
1787+ compareValues (tp1, tp2)
17861788 }
17871789
17881790 /** Test whether value type `tp1` is as good as value type `tp2`.
@@ -1812,6 +1814,7 @@ trait Applications extends Compatibility {
18121814 * for overloading resolution (when `preferGeneral is false), and the opposite relation
18131815 * `U <: T` or `U convertible to `T` for implicit disambiguation between givens
18141816 * (when `preferGeneral` is true). For old-style implicit values, the 3.4 behavior is kept.
1817+ * If one of the alternatives is a given and the other is an implicit, the given wins.
18151818 *
18161819 * - In Scala 3.5-migration, use the 3.5 scheme normally, and the 3.4 scheme if
18171820 * `Mode.OldImplicitResolution` is on. This is used to highlight differences in the
@@ -1820,7 +1823,7 @@ trait Applications extends Compatibility {
18201823 * Also and only for given resolution: If a compared type refers to a given or its module class, use
18211824 * the intersection of its parent classes instead.
18221825 */
1823- def isAsGoodValueType (tp1 : Type , tp2 : Type )(using Context ) =
1826+ def isAsGoodValueType (tp1 : Type , tp2 : Type , alt1isGiven : Boolean , alt2isGiven : Boolean )(using Context ): Boolean =
18241827 val oldResolution = ctx.mode.is(Mode .OldImplicitResolution )
18251828 if ! preferGeneral || Feature .migrateTo3 && oldResolution then
18261829 // Normal specificity test for overloading resolution (where `preferGeneral` is false)
@@ -1838,7 +1841,7 @@ trait Applications extends Compatibility {
18381841
18391842 if Feature .sourceVersion.isAtMost(SourceVersion .`3.4`)
18401843 || oldResolution
1841- || ! compareGivens
1844+ || ! alt1isGiven && ! alt2isGiven
18421845 then
18431846 // Intermediate rules: better means specialize, but map all type arguments downwards
18441847 // These are enabled for 3.0-3.4, and for all comparisons between old-style implicits,
@@ -1853,8 +1856,9 @@ trait Applications extends Compatibility {
18531856 case _ => mapOver(t)
18541857 (flip(tp1p) relaxed_<:< flip(tp2p)) || viewExists(tp1, tp2)
18551858 else
1856- // New rules: better means generalize
1857- (tp2p relaxed_<:< tp1p) || viewExists(tp2, tp1)
1859+ // New rules: better means generalize, givens always beat implicits
1860+ if alt1isGiven != alt2isGiven then alt1isGiven
1861+ else (tp2p relaxed_<:< tp1p) || viewExists(tp2, tp1)
18581862 end isAsGoodValueType
18591863
18601864 /** Widen the result type of synthetic given methods from the implementation class to the
@@ -1907,8 +1911,8 @@ trait Applications extends Compatibility {
19071911 def comparePrefixes =
19081912 val pre1 = widenPrefix(alt1)
19091913 val pre2 = widenPrefix(alt2)
1910- val winsPrefix1 = isAsGoodValueType (pre1, pre2)
1911- val winsPrefix2 = isAsGoodValueType (pre2, pre1)
1914+ val winsPrefix1 = isCompatible (pre1, pre2)
1915+ val winsPrefix2 = isCompatible (pre2, pre1)
19121916 if winsPrefix1 == winsPrefix2 then 0
19131917 else if winsPrefix1 then 1
19141918 else - 1
0 commit comments