Skip to content

Commit 34b7bab

Browse files
committed
Don't approximate a type using Nothing as prefix
Approximate range(Nothing, hi) to Nothing & hi instead of Nothing. This avoids creating TypeRefs with a Nothing prefix which manifest themselves down the line with an error like: Cannot resolve reference to type path.type.AbsMember. The classfile defining the type might be missing from the classpath. val z1 = transition(di).ext(1) // error ^ Due to a MissingType thrown from TypeErasure#sigName Fixes #23530
1 parent 03a54a7 commit 34b7bab

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6482,9 +6482,24 @@ object Types extends TypeUtils {
64826482
abstract class ApproximatingTypeMap(using Context) extends TypeMap { thisMap =>
64836483

64846484
protected def range(lo: Type, hi: Type): Type =
6485-
if (variance > 0) hi
6486-
else if (variance < 0) lo
6487-
else if (lo `eq` hi) lo
6485+
if variance > 0 then hi
6486+
else if variance < 0 then
6487+
if (lo eq defn.NothingType) && hi.hasSimpleKind then
6488+
// Approximate by Nothing & hi instead of just Nothing, in case the
6489+
// approximated type is used as the prefix of another type (this would
6490+
// lead to a type with a `NoDenotation` denot and a possible
6491+
// MissingType in `TypeErasure#sigName`).
6492+
//
6493+
// Note that we cannot simply check for a `Nothing` prefix in
6494+
// `derivedSelect`, because the substitution might be done lazily (for
6495+
// example if Nothing is the type of a parameter being depended on in
6496+
// a MethodType)
6497+
//
6498+
// Test case in tests/pos/i23530.scala
6499+
AndType(lo, hi)
6500+
else
6501+
lo
6502+
else if lo `eq` hi then lo
64886503
else Range(lower(lo), upper(hi))
64896504

64906505
protected def emptyRange = range(defn.NothingType, defn.AnyType)

tests/pos/i23530.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:
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)