Skip to content

Commit 8159725

Browse files
committed
Final versioning scheme
1 parent 87803b0 commit 8159725

File tree

8 files changed

+43
-22
lines changed

8 files changed

+43
-22
lines changed

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1749,12 +1749,13 @@ trait Applications extends Compatibility {
17491749
val tp1p = prepare(tp1)
17501750
val tp2p = prepare(tp2)
17511751

1752-
if Feature.sourceVersion.isAtMost(SourceVersion.`3.3`) // !!! change to 3.4
1752+
if Feature.sourceVersion.isAtMost(SourceVersion.`3.4`)
17531753
|| oldResolution
17541754
|| !compareGivens
17551755
then
17561756
// Intermediate rules: better means specialize, but map all type arguments downwards
1757-
// These are enabled for 3.0-3.4, and in 3.5-migration when we compare with previous rules
1757+
// These are enabled for 3.0-3.4, and for all comparisons between old-style implicits,
1758+
// and in 3.5-migration when we compare with previous rules.
17581759
val flip = new TypeMap:
17591760
def apply(t: Type) = t match
17601761
case t @ AppliedType(tycon, args) =>

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

+14-19
Original file line numberDiff line numberDiff line change
@@ -1290,27 +1290,22 @@ trait Implicits:
12901290
*/
12911291
def compareAlternatives(alt1: RefAndLevel, alt2: RefAndLevel): Int =
12921292
def comp(using Context) = explore(compare(alt1.ref, alt2.ref, preferGeneral = true))
1293-
def oldCompare() = comp(using searchContext().addMode(Mode.OldOverloadingResolution))
1294-
def newCompare() = comp(using searchContext())
1295-
12961293
if alt1.ref eq alt2.ref then 0
12971294
else if alt1.level != alt2.level then alt1.level - alt2.level
1298-
else if Feature.sourceVersion.isAtMost(SourceVersion.`3.3`) then // !!! change to 3.4
1299-
oldCompare()
1300-
else if Feature.sourceVersion == SourceVersion.`3.5-migration` || true then // !!! drop
1301-
val was = oldCompare()
1302-
val now = newCompare()
1303-
if was != now then
1304-
def choice(cmp: Int) = cmp match
1305-
case -1 => "the second alternative"
1306-
case 1 => "the first alternative"
1307-
case _ => "none - it's ambiguous"
1308-
report.warning(
1309-
em"""Change in given search preference for $pt between alternatives ${alt1.ref} and ${alt2.ref}
1310-
|Previous choice: ${choice(was)}
1311-
|New choice : ${choice(now)}""", srcPos)
1312-
now
1313-
else newCompare()
1295+
else
1296+
val cmp = comp(using searchContext())
1297+
if Feature.sourceVersion == SourceVersion.`3.5-migration` then
1298+
val prev = comp(using searchContext().addMode(Mode.OldOverloadingResolution))
1299+
if cmp != prev then
1300+
def choice(c: Int) = c match
1301+
case -1 => "the second alternative"
1302+
case 1 => "the first alternative"
1303+
case _ => "none - it's ambiguous"
1304+
report.warning(
1305+
em"""Change in given search preference for $pt between alternatives ${alt1.ref} and ${alt2.ref}
1306+
|Previous choice: ${choice(prev)}
1307+
|New choice : ${choice(cmp)}""", srcPos)
1308+
cmp
13141309
end compareAlternatives
13151310

13161311
/** If `alt1` is also a search success, try to disambiguate as follows:

docs/_docs/reference/changed-features/implicit-resolution.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,20 @@ The new rules are as follows: An implicit `a` defined in `A` is more specific th
163163

164164
Condition (*) is new. It is necessary to ensure that the defined relation is transitive.
165165

166+
[//]: # todo: expand with precise rules
166167

167168

169+
**9.** Given disambiguation has changed. When comparing two givens that both match an expected type, we used to pick the most specific one, in alignment with
170+
overloading resolution. From Scala 3.5 on, we pick the most general one instead. Compiling with Scala 3.5-migration will print a warning in all cases where the preference has changed. Example:
171+
```scala
172+
class A
173+
class B extends A
174+
class C extends A
168175

176+
given A = A()
177+
given B = B()
178+
given C = C()
179+
180+
summon[A] // was ambiguous, will now return `given_A`
181+
```
169182

170-
[//]: # todo: expand with precise rules

tests/neg/i15264.scala

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import language.`3.5`
12
object priority:
23
// lower number = higher priority
34
class Prio0 extends Prio1

tests/neg/implicit-arg.scala

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class C
2+
3+
def foo(using C) = ()
4+
5+
def Test =
6+
val c = C()
7+
foo(c)

tests/run/given-triangle.scala

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import language.`3.5`
2+
13
class A
24
class B extends A
35
class C extends A

tests/run/implicit-specifity.scala

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import language.`3.5`
2+
13
case class Show[T](val i: Int)
24
object Show {
35
def apply[T](implicit st: Show[T]): Int = st.i

tests/run/implied-priority.scala

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* These tests show various mechanisms available for implicit prioritization.
22
*/
3+
import language.`3.5`
34

45
class E[T](val str: String) // The type for which we infer terms below
56

0 commit comments

Comments
 (0)