Skip to content

Commit b476bb6

Browse files
committed
Try not to update denotations that contains skolem types
1 parent 2680d2a commit b476bb6

File tree

5 files changed

+90
-11
lines changed

5 files changed

+90
-11
lines changed

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

+36-11
Original file line numberDiff line numberDiff line change
@@ -2455,21 +2455,36 @@ object Types extends TypeUtils {
24552455
d
24562456
}
24572457

2458-
def fromDesignator = designator match {
2458+
def fromDesignator(lastdMaybe: Option[SingleDenotation]) = designator match {
24592459
case name: Name =>
24602460
val sym = lastSymbol
24612461
val allowPrivate = sym == null || (sym == NoSymbol) || sym.lastKnownDenotation.flagsUNSAFE.is(Private)
24622462
finish(memberDenot(name, allowPrivate))
24632463
case sym: Symbol =>
24642464
val symd = sym.lastKnownDenotation
2465-
if (symd.validFor.runId != ctx.runId && !stillValid(symd))
2466-
finish(memberDenot(symd.initial.name, allowPrivate = false))
2467-
else if (prefix.isArgPrefixOf(symd))
2468-
finish(argDenot(sym.asType))
2469-
else if (infoDependsOnPrefix(symd, prefix))
2470-
finish(memberDenot(symd.initial.name, allowPrivate = symd.is(Private)))
2471-
else
2472-
finish(symd.current)
2465+
if (symd.validFor.runId != ctx.runId && !stillValid(symd))
2466+
val res0 = memberDenot(symd.initial.name, allowPrivate = false)
2467+
val res = lastdMaybe match
2468+
case Some(lastd) if hasSkolems(lastd.info) =>
2469+
// When updating denotation, changing types from skolem may cause issues
2470+
// with other parts of the tree
2471+
finish(lastd.derivedSingleDenotation(res0.symbol, lastd.info, prefix))
2472+
case _ =>
2473+
res0
2474+
finish(res)
2475+
else if (prefix.isArgPrefixOf(symd))
2476+
finish(argDenot(sym.asType))
2477+
else if (infoDependsOnPrefix(symd, prefix))
2478+
val res = lastdMaybe match
2479+
case Some(lastd) if hasSkolems(lastd.info) =>
2480+
// When updating denotation, changing types from skolem may cause issues
2481+
// with other parts of the tree
2482+
finish(lastd.derivedSingleDenotation(sym, lastd.info, prefix))
2483+
case _ =>
2484+
memberDenot(symd.initial.name, allowPrivate = symd.is(Private))
2485+
finish(res)
2486+
else
2487+
finish(symd.current)
24732488
}
24742489

24752490
lastDenotation match {
@@ -2482,9 +2497,9 @@ object Types extends TypeUtils {
24822497
if stillValid(lastd) && checkedPeriod.code != NowhereCode then finish(lastd.current)
24832498
else finish(memberDenot(lastd.initial.name, allowPrivate = lastd.is(Private)))
24842499
case _ =>
2485-
fromDesignator
2500+
fromDesignator(Some(lastd))
24862501
}
2487-
case _ => fromDesignator
2502+
case _ => fromDesignator(None)
24882503
}
24892504
}
24902505

@@ -7024,6 +7039,16 @@ object Types extends TypeUtils {
70247039
def isStable = true
70257040
}
70267041

7042+
def hasSkolems(tpe: Type)(using Context) =
7043+
object hasSkolemsAcc extends TypeAccumulator[Boolean]:
7044+
def apply(x: Boolean, tp: Type): Boolean =
7045+
x || {
7046+
tp match
7047+
case _: SkolemType => true
7048+
case _ => foldOver(false, tp)
7049+
}
7050+
hasSkolemsAcc(false, tpe)
7051+
70277052
// ----- Debug ---------------------------------------------------------
70287053

70297054
@sharable var debugTrace: Boolean = false

tests/pos-macros/i22585-b/Macro.scala

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import scala.quoted.*
2+
3+
object Hammer2 {
4+
inline def makeProductHammerMacro[I, O](): Hammer[I, O] =
5+
${ makeProductHammerMacroImpl[I, O] }
6+
7+
def makeProductHammerMacroImpl[I: Type, O: Type](using Quotes): Expr[Hammer[I, O]] =
8+
'{ makeHammer[I, O]() }
9+
10+
inline def makeHammer[S, O](): Hammer[S, O] =
11+
new Hammer[S, O] {
12+
lazy val (hammer: Hammer[?, Int], idx: Int) = ???
13+
14+
override def hammer(input: S): O = {
15+
hammer.hammer(???.asInstanceOf).asInstanceOf[O]
16+
}
17+
}
18+
}

tests/pos-macros/i22585-b/Test.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trait Hammer[I, O] {
2+
def hammer(input: I): O
3+
}
4+
5+
object HammerSpec {
6+
case class A(x: Int)
7+
case class B(x: Int)
8+
Hammer2.makeProductHammerMacro[A, B]()
9+
}

tests/pos-macros/i22585-c/Macro.scala

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import scala.quoted.*
2+
3+
trait Hammer[I, O] {
4+
def hammer(input: I): O
5+
}
6+
7+
object Hammer {
8+
inline def makeProductHammerMacro[I, O](): Hammer[I, O] =
9+
${ makeProductHammerMacroImpl[I, O] }
10+
11+
def makeProductHammerMacroImpl[I: Type, O: Type](using Quotes): Expr[Hammer[I, O]] =
12+
'{ makeHammer[I, O]() }
13+
14+
inline def makeHammer[S, O](): Hammer[S, O] =
15+
new Hammer[S, O] {
16+
lazy val (hammer: Hammer[?, Int], idx: Int) = ???
17+
18+
override def hammer(input: S): O = {
19+
hammer.hammer(???.asInstanceOf).asInstanceOf[O]
20+
}
21+
}
22+
}

tests/pos-macros/i22585-c/Test.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object HammerSpec {
2+
case class A(x: Int)
3+
case class B(x: Int)
4+
Hammer.makeProductHammerMacro[A, B]()
5+
}

0 commit comments

Comments
 (0)