From c6ffa06e3fe575994c793a8572a547b0636a3b39 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 26 Jun 2025 17:36:21 +0200 Subject: [PATCH 1/2] Fix regressions in asSeenFrom introduced in 3.7 The body of isLegalPrefix used to read: pre.isStable || !ctx.phase.isTyper but was changed to drop the second condition in #21954 (originally included in 3.6.4-RC1, reverted from 3.6.4 final but back in 3.7). This has led to a number of regressions, the last ones discussed in #23423. To make the testcases added in #21594 pass, this PR proposes a less drastic change: relax isLegalPrefix as before, unless we're doing an implicit search. This should dramatically reduce the possibility for regressions. Fixes #23423. Fixes #22676. --- compiler/src/dotty/tools/dotc/core/TypeOps.scala | 4 +++- tests/neg-custom-args/captures/lazylist.check | 10 +++++----- tests/pos-macros/i23423/A_1.scala | 16 ++++++++++++++++ tests/pos-macros/i23423/B_2.scala | 6 ++++++ tests/pos/i22676.scala | 11 +++++++++++ 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 tests/pos-macros/i23423/A_1.scala create mode 100644 tests/pos-macros/i23423/B_2.scala create mode 100644 tests/pos/i22676.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index c985ed23274b..8b2f34608193 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -123,7 +123,9 @@ object TypeOps: } def isLegalPrefix(pre: Type)(using Context): Boolean = - pre.isStable || !ctx.phase.isTyper + // isLegalPrefix is relaxed after typer unless we're doing an implicit + // search (this matters when doing summonInline in an inline def like in tests/pos/i17222.8.scala). + pre.isStable || !ctx.phase.isTyper && ctx.mode.is(Mode.ImplicitsEnabled) /** Implementation of Types#simplified */ def simplify(tp: Type, theMap: SimplifyMap | Null)(using Context): Type = { diff --git a/tests/neg-custom-args/captures/lazylist.check b/tests/neg-custom-args/captures/lazylist.check index 4b7611fc3fb7..59e2ee251b86 100644 --- a/tests/neg-custom-args/captures/lazylist.check +++ b/tests/neg-custom-args/captures/lazylist.check @@ -26,11 +26,11 @@ | Required: lazylists.LazyList[Int]^{cap2} | | longer explanation available when compiling with `-explain` --- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:41:48 ------------------------------------- -41 | val ref4c: LazyList[Int]^{cap1, ref3, cap3} = ref4 // error - | ^^^^ - | Found: (ref4 : lazylists.LazyList[Int]^{cap3, cap2, ref1, cap1}) - | Required: lazylists.LazyList[Int]^{cap1, ref3, cap3} +-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:41:42 ------------------------------------- +41 | val ref4c: LazyList[Int]^{cap1, ref3} = ref4 // error + | ^^^^ + | Found: (ref4 : lazylists.LazyList[Int]^{cap3, cap1, cap2}) + | Required: lazylists.LazyList[Int]^{cap1, ref3} | | longer explanation available when compiling with `-explain` -- [E164] Declaration Error: tests/neg-custom-args/captures/lazylist.scala:22:6 ---------------------------------------- diff --git a/tests/pos-macros/i23423/A_1.scala b/tests/pos-macros/i23423/A_1.scala new file mode 100644 index 000000000000..62455c74eed0 --- /dev/null +++ b/tests/pos-macros/i23423/A_1.scala @@ -0,0 +1,16 @@ +package pkg + +import scala.quoted.* + +trait HasElem { + type Elem + type Alias = Elem +} + +object Macro: + inline def foo: Unit = ${fooImpl} + def fooImpl(using Quotes): Expr[Unit] = + '{ + val lll: (he: HasElem) => he.Alias = + (hx: HasElem) => ??? + } diff --git a/tests/pos-macros/i23423/B_2.scala b/tests/pos-macros/i23423/B_2.scala new file mode 100644 index 000000000000..144eaf4ce1da --- /dev/null +++ b/tests/pos-macros/i23423/B_2.scala @@ -0,0 +1,6 @@ +object Test: + def test: Unit = pkg.Macro.foo + // used to be error: + // Found: (hx: pkg.HasElem) => hx.Elem + // Required: (he: pkg.HasElem) => he.Elem + diff --git a/tests/pos/i22676.scala b/tests/pos/i22676.scala new file mode 100644 index 000000000000..5654559b133f --- /dev/null +++ b/tests/pos/i22676.scala @@ -0,0 +1,11 @@ +package example + +trait Example { + class Input + + type Output[A] = A match { + case Input => Int + } +} + +class Ref(ref: Example#Input) From a24216f5ef89f0b60922a929d7d7d3ed0c931b78 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Mon, 30 Jun 2025 17:17:33 +0200 Subject: [PATCH 2/2] Fix regressions in asSeenFrom introduced in 3.7 The body of isLegalPrefix used to read: pre.isStable || !ctx.phase.isTyper but was changed to drop the second condition in #21954 (originally included in 3.6.4-RC1, reverted from 3.6.4 final but back in 3.7). This has led to a number of regressions, the last ones discussed in #23423. To make the testcases added in #21594 pass, this PR proposes a less drastic change: relax isLegalPrefix as before, unless we're doing an implicit search. This should dramatically reduce the possibility for regressions. Fixes #23423. Fixes #22676. [Cherry-picked 2e4bc0abb8a374d78fe1aac383f3208b5efb5eb1][modified]