Skip to content

Commit 1e1b9a4

Browse files
smartertgodzik
authored andcommitted
Generalize "Don't approximate a type using Nothing as prefix"
This generalizes scala#23531 which skipped higher-kinded types, turns out approximating them to Nothing can lead to the same issue. Fixes scala#23627. [Cherry-picked 1ea24d6]
1 parent 9de5e1f commit 1e1b9a4

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
@@ -6073,7 +6073,7 @@ object Types extends TypeUtils {
60736073
protected def range(lo: Type, hi: Type): Type =
60746074
if variance > 0 then hi
60756075
else if variance < 0 then
6076-
if (lo eq defn.NothingType) && hi.hasSimpleKind then
6076+
if (lo eq defn.NothingType) then
60776077
// Approximate by Nothing & hi instead of just Nothing, in case the
60786078
// approximated type is used as the prefix of another type (this would
60796079
// lead to a type with a `NoDenotation` denot and a possible
@@ -6084,8 +6084,14 @@ object Types extends TypeUtils {
60846084
// example if Nothing is the type of a parameter being depended on in
60856085
// a MethodType)
60866086
//
6087-
// Test case in tests/pos/i23530.scala
6088-
AndType(lo, hi)
6087+
// Test case in tests/pos/i23530.scala (and tests/pos/i23627.scala for
6088+
// the higher-kinded case which requires eta-expansion)
6089+
hi.etaExpand match
6090+
case expandedHi: HKTypeLambda =>
6091+
expandedHi.derivedLambdaType(resType = AndType(lo, expandedHi.resType))
6092+
case _ =>
6093+
// simple-kinded case
6094+
AndType(lo, hi)
60896095
else
60906096
lo
60916097
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)