From 1ea24d6a89cb88a9f51b76f9fd17ffd424e4f9e1 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 29 Jul 2025 19:43:52 +0200 Subject: [PATCH] Generalize "Don't approximate a type using Nothing as prefix" This generalizes https://github.com/scala/scala3/pull/23531 which skipped higher-kinded types, turns out approximating them to Nothing can lead to the same issue. Fixes #23627. --- compiler/src/dotty/tools/dotc/core/Types.scala | 12 +++++++++--- tests/pos/i23627.scala | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i23627.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index a6f59d8b2d33..7fac8c818a1a 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -6507,7 +6507,7 @@ object Types extends TypeUtils { protected def range(lo: Type, hi: Type): Type = if variance > 0 then hi else if variance < 0 then - if (lo eq defn.NothingType) && hi.hasSimpleKind then + if (lo eq defn.NothingType) then // Approximate by Nothing & hi instead of just Nothing, in case the // approximated type is used as the prefix of another type (this would // lead to a type with a `NoDenotation` denot and a possible @@ -6518,8 +6518,14 @@ object Types extends TypeUtils { // example if Nothing is the type of a parameter being depended on in // a MethodType) // - // Test case in tests/pos/i23530.scala - AndType(lo, hi) + // Test case in tests/pos/i23530.scala (and tests/pos/i23627.scala for + // the higher-kinded case which requires eta-expansion) + hi.etaExpand match + case expandedHi: HKTypeLambda => + expandedHi.derivedLambdaType(resType = AndType(lo, expandedHi.resType)) + case _ => + // simple-kinded case + AndType(lo, hi) else lo else if lo `eq` hi then lo diff --git a/tests/pos/i23627.scala b/tests/pos/i23627.scala new file mode 100644 index 000000000000..1480a80c9c00 --- /dev/null +++ b/tests/pos/i23627.scala @@ -0,0 +1,18 @@ +trait TestContainer: + trait TestPath[T]: + type AbsMember + + extension (path: TestPath[?]) + infix def ext(color: path.AbsMember): Unit = ??? + infix def ext(other: Int): Unit = ??? + +object Repro: + val dc2: TestContainer = ??? + import dc2.TestPath + + def transition(path: TestPath[?])(using DummyImplicit): TestPath[?] = ??? + + def test: Unit = + val di: TestPath[?] = ??? + // error + val z1 = transition(di).ext(1)