Skip to content

Commit e0862a3

Browse files
authored
Generalize "Don't approximate a type using Nothing as prefix" (#23628)
This generalizes #23531 which skipped higher-kinded types, turns out approximating them to Nothing can lead to the same issue. Fixes #23627.
2 parents b0627b3 + 1ea24d6 commit e0862a3

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6507,7 +6507,7 @@ object Types extends TypeUtils {
65076507
protected def range(lo: Type, hi: Type): Type =
65086508
if variance > 0 then hi
65096509
else if variance < 0 then
6510-
if (lo eq defn.NothingType) && hi.hasSimpleKind then
6510+
if (lo eq defn.NothingType) then
65116511
// Approximate by Nothing & hi instead of just Nothing, in case the
65126512
// approximated type is used as the prefix of another type (this would
65136513
// lead to a type with a `NoDenotation` denot and a possible
@@ -6518,8 +6518,14 @@ object Types extends TypeUtils {
65186518
// example if Nothing is the type of a parameter being depended on in
65196519
// a MethodType)
65206520
//
6521-
// Test case in tests/pos/i23530.scala
6522-
AndType(lo, hi)
6521+
// Test case in tests/pos/i23530.scala (and tests/pos/i23627.scala for
6522+
// the higher-kinded case which requires eta-expansion)
6523+
hi.etaExpand match
6524+
case expandedHi: HKTypeLambda =>
6525+
expandedHi.derivedLambdaType(resType = AndType(lo, expandedHi.resType))
6526+
case _ =>
6527+
// simple-kinded case
6528+
AndType(lo, hi)
65236529
else
65246530
lo
65256531
else if lo `eq` hi then lo

tests/pos/i23627.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
trait TestContainer:
2+
trait TestPath[T]:
3+
type AbsMember
4+
5+
extension (path: TestPath[?])
6+
infix def ext(color: path.AbsMember): Unit = ???
7+
infix def ext(other: Int): Unit = ???
8+
9+
object Repro:
10+
val dc2: TestContainer = ???
11+
import dc2.TestPath
12+
13+
def transition(path: TestPath[?])(using DummyImplicit): TestPath[?] = ???
14+
15+
def test: Unit =
16+
val di: TestPath[?] = ???
17+
// error
18+
val z1 = transition(di).ext(1)

0 commit comments

Comments
 (0)