Skip to content

Commit 6688751

Browse files
Drop prioritization of givens over implicits
But keep the exception that NotGiven has lower priority
1 parent 656b7af commit 6688751

File tree

1 file changed

+7
-9
lines changed

1 file changed

+7
-9
lines changed

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,7 +1831,8 @@ trait Applications extends Compatibility {
18311831
}
18321832
case _ => // (3)
18331833
def compareValues(tp1: Type, tp2: Type)(using Context) =
1834-
isAsGoodValueType(tp1, tp2, alt1.symbol.is(Implicit), alt2.symbol.is(Implicit))
1834+
extension (alt: TermRef) def isNotGivenClass: Boolean = alt.symbol == defn.NotGivenClass
1835+
isAsGoodValueType(tp1, tp2, alt1.isNotGivenClass, alt2.isNotGivenClass)
18351836
tp2 match
18361837
case tp2: MethodType => true // (3a)
18371838
case tp2: PolyType if tp2.resultType.isInstanceOf[MethodType] => true // (3a)
@@ -1868,15 +1869,15 @@ trait Applications extends Compatibility {
18681869
* for overloading resolution (when `preferGeneral is false), and the opposite relation
18691870
* `U <: T` or `U convertible to `T` for implicit disambiguation between givens
18701871
* (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.
1872+
* If one of the alternatives is a NotGivenClass, and the other is not, then the NotGivenClass loses.
18721873
*
18731874
* - In Scala 3.5 and Scala 3.6-migration, we issue a warning if the result under
18741875
* Scala 3.6 differ wrt to the old behavior up to 3.5.
18751876
*
18761877
* Also and only for given resolution: If a compared type refers to a given or its module class, use
18771878
* the intersection of its parent classes instead.
18781879
*/
1879-
def isAsGoodValueType(tp1: Type, tp2: Type, alt1IsImplicit: Boolean, alt2IsImplicit: Boolean)(using Context): Boolean =
1880+
def isAsGoodValueType(tp1: Type, tp2: Type, alt1IsNotGivenClass: Boolean, alt2IsNotGivenClass: Boolean)(using Context): Boolean =
18801881
val oldResolution = ctx.mode.is(Mode.OldImplicitResolution)
18811882
if !preferGeneral || Feature.migrateTo3 && oldResolution then
18821883
// Normal specificity test for overloading resolution (where `preferGeneral` is false)
@@ -1892,10 +1893,7 @@ trait Applications extends Compatibility {
18921893
val tp1p = prepare(tp1)
18931894
val tp2p = prepare(tp2)
18941895

1895-
if Feature.sourceVersion.isAtMost(SourceVersion.`3.4`)
1896-
|| oldResolution
1897-
|| alt1IsImplicit && alt2IsImplicit
1898-
then
1896+
if Feature.sourceVersion.isAtMost(SourceVersion.`3.4`) || oldResolution then
18991897
// Intermediate rules: better means specialize, but map all type arguments downwards
19001898
// These are enabled for 3.0-3.5, and for all comparisons between old-style implicits,
19011899
// and in 3.5 and 3.6-migration when we compare with previous rules.
@@ -1909,8 +1907,8 @@ trait Applications extends Compatibility {
19091907
case _ => mapOver(t)
19101908
(flip(tp1p) relaxed_<:< flip(tp2p)) || viewExists(tp1, tp2)
19111909
else
1912-
// New rules: better means generalize, givens (and extensions) always beat implicits
1913-
if alt1IsImplicit != alt2IsImplicit then alt2IsImplicit
1910+
// New rules: better means generalize, except `NotGivenClass` which is given lower priority
1911+
if alt1IsNotGivenClass != alt2IsNotGivenClass then alt2IsNotGivenClass
19141912
else (tp2p relaxed_<:< tp1p) || viewExists(tp2, tp1)
19151913
end isAsGoodValueType
19161914

0 commit comments

Comments
 (0)