@@ -1830,15 +1830,13 @@ trait Applications extends Compatibility {
18301830 isAsGood(alt1, tp1.instantiate(tparams.map(_.typeRef)), alt2, tp2)
18311831 }
18321832 case _ => // (3)
1833- def compareValues (tp1 : Type , tp2 : Type )(using Context ) =
1834- isAsGoodValueType(tp1, tp2, alt1.symbol.is(Implicit ), alt2.symbol.is(Implicit ))
18351833 tp2 match
18361834 case tp2 : MethodType => true // (3a)
18371835 case tp2 : PolyType if tp2.resultType.isInstanceOf [MethodType ] => true // (3a)
18381836 case tp2 : PolyType => // (3b)
1839- explore(compareValues (tp1, instantiateWithTypeVars(tp2)))
1837+ explore(isAsGoodValueType (tp1, instantiateWithTypeVars(tp2)))
18401838 case _ => // 3b)
1841- compareValues (tp1, tp2)
1839+ isAsGoodValueType (tp1, tp2)
18421840 }
18431841
18441842 /** Test whether value type `tp1` is as good as value type `tp2`.
@@ -1868,15 +1866,14 @@ trait Applications extends Compatibility {
18681866 * for overloading resolution (when `preferGeneral is false), and the opposite relation
18691867 * `U <: T` or `U convertible to `T` for implicit disambiguation between givens
18701868 * (when `preferGeneral` is true). For old-style implicit values, the 3.4 behavior is kept.
1871- * If one of the alternatives is an implicit and the other is a given (or an extension), the implicit loses.
18721869 *
18731870 * - In Scala 3.5 and Scala 3.6-migration, we issue a warning if the result under
18741871 * Scala 3.6 differ wrt to the old behavior up to 3.5.
18751872 *
18761873 * Also and only for given resolution: If a compared type refers to a given or its module class, use
18771874 * the intersection of its parent classes instead.
18781875 */
1879- def isAsGoodValueType (tp1 : Type , tp2 : Type , alt1IsImplicit : Boolean , alt2IsImplicit : Boolean )(using Context ): Boolean =
1876+ def isAsGoodValueType (tp1 : Type , tp2 : Type )(using Context ): Boolean =
18801877 val oldResolution = ctx.mode.is(Mode .OldImplicitResolution )
18811878 if ! preferGeneral || Feature .migrateTo3 && oldResolution then
18821879 // Normal specificity test for overloading resolution (where `preferGeneral` is false)
@@ -1892,10 +1889,7 @@ trait Applications extends Compatibility {
18921889 val tp1p = prepare(tp1)
18931890 val tp2p = prepare(tp2)
18941891
1895- if Feature .sourceVersion.isAtMost(SourceVersion .`3.4`)
1896- || oldResolution
1897- || alt1IsImplicit && alt2IsImplicit
1898- then
1892+ if Feature .sourceVersion.isAtMost(SourceVersion .`3.4`) || oldResolution then
18991893 // Intermediate rules: better means specialize, but map all type arguments downwards
19001894 // These are enabled for 3.0-3.5, and for all comparisons between old-style implicits,
19011895 // and in 3.5 and 3.6-migration when we compare with previous rules.
@@ -1909,9 +1903,8 @@ trait Applications extends Compatibility {
19091903 case _ => mapOver(t)
19101904 (flip(tp1p) relaxed_<:< flip(tp2p)) || viewExists(tp1, tp2)
19111905 else
1912- // New rules: better means generalize, givens (and extensions) always beat implicits
1913- if alt1IsImplicit != alt2IsImplicit then alt2IsImplicit
1914- else (tp2p relaxed_<:< tp1p) || viewExists(tp2, tp1)
1906+ // New rules: better means generalize
1907+ (tp2p relaxed_<:< tp1p) || viewExists(tp2, tp1)
19151908 end isAsGoodValueType
19161909
19171910 /** Widen the result type of synthetic given methods from the implementation class to the
@@ -1970,8 +1963,9 @@ trait Applications extends Compatibility {
19701963 else if winsPrefix1 then 1
19711964 else - 1
19721965
1966+ val ownerScore = compareOwner(alt1.symbol.maybeOwner, alt2.symbol.maybeOwner)
1967+
19731968 def compareWithTypes (tp1 : Type , tp2 : Type ) =
1974- val ownerScore = compareOwner(alt1.symbol.maybeOwner, alt2.symbol.maybeOwner)
19751969 val winsType1 = isAsGood(alt1, tp1, alt2, tp2)
19761970 val winsType2 = isAsGood(alt2, tp2, alt1, tp1)
19771971
@@ -1982,15 +1976,27 @@ trait Applications extends Compatibility {
19821976 // alternatives are the same after following ExprTypes, pick one of them
19831977 // (prefer the one that is not a method, but that's arbitrary).
19841978 if alt1.widenExpr =:= alt2 then - 1 else 1
1985- else ownerScore match
1986- case 1 => if winsType1 || ! winsType2 then 1 else 0
1987- case - 1 => if winsType2 || ! winsType1 then - 1 else 0
1988- case 0 =>
1989- if winsType1 != winsType2 then if winsType1 then 1 else - 1
1990- else if alt1.symbol == alt2.symbol then comparePrefixes
1991- else 0
1979+ else
1980+ ownerScore match
1981+ case 1 => if winsType1 || ! winsType2 then 1 else 0
1982+ case - 1 => if winsType2 || ! winsType1 then - 1 else 0
1983+ case 0 =>
1984+ if winsType1 != winsType2 then if winsType1 then 1 else - 1
1985+ else if alt1.symbol == alt2.symbol then comparePrefixes
1986+ else 0
19921987 end compareWithTypes
19931988
1989+ // For implicit resolution, take ownerscore as more significant than type resolution
1990+ // Reason: People use owner hierarchies to explicitly prioritize, we should not
1991+ // break that by changing implicit priority of types. On the other hand, we do
1992+ // want to exhaust all other possibilities before using owner score as a tie breaker.
1993+ // For instance, pos/scala-uri.scala depends on that.
1994+ def drawOrOwner =
1995+ if preferGeneral && ! ctx.mode.is(Mode .OldImplicitResolution ) then
1996+ // println(i"disambi compare($alt1, $alt2)? $ownerScore")
1997+ ownerScore
1998+ else 0
1999+
19942000 if alt1.symbol.is(ConstructorProxy ) && ! alt2.symbol.is(ConstructorProxy ) then - 1
19952001 else if alt2.symbol.is(ConstructorProxy ) && ! alt1.symbol.is(ConstructorProxy ) then 1
19962002 else
@@ -2000,11 +2006,12 @@ trait Applications extends Compatibility {
20002006 val strippedType2 = stripImplicit(fullType2)
20012007
20022008 val result = compareWithTypes(strippedType1, strippedType2)
2003- if (result != 0 ) result
2004- else if (strippedType1 eq fullType1)
2005- if (strippedType2 eq fullType2) 0 // no implicits either side: its' a draw
2009+ if result != 0 then result
2010+ else if strippedType1 eq fullType1 then
2011+ if strippedType2 eq fullType2
2012+ then drawOrOwner // no implicits either side: its' a draw
20062013 else 1 // prefer 1st alternative with no implicits
2007- else if ( strippedType2 eq fullType2) - 1 // prefer 2nd alternative with no implicits
2014+ else if strippedType2 eq fullType2 then - 1 // prefer 2nd alternative with no implicits
20082015 else compareWithTypes(fullType1, fullType2) // continue by comparing implicits parameters
20092016 }
20102017 end compare
0 commit comments