Skip to content

Commit

Permalink
Set the inlining phase in the Context used for checking macro trees (s…
Browse files Browse the repository at this point in the history
…cala#20087)

Fixes scala#17009 
The problem here was with the sub typing check for `line.split(" ").nn`,
which needed to confirm that:

```scala
(?2 : Array[String]) & Array[String]  <:  (?1 : Array[String]) & Array[String]
```
`TypeComparer` would eventually try to compare two skolem types:
```scala
(?2 : Array[String]) <: (?1 : Array[String])
```
The behavior of `TypeComparer` differs here when executed during the
typer phase, where it always returns false for two skolem types, without
checking the sub typing further. This makes sense for Typer, but not so
much for the macro checks, which for `transparent inline`s end up being
executed during Typer. I think the best solution here is to artificially
change the phase in the checkingContext, so the checks done for
transparent and non-transparent macros are the same.
  • Loading branch information
nicolasstucki authored Apr 5, 2024
2 parents f3139cd + 9f5618b commit b8fb81b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 0 deletions.
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -837,9 +837,19 @@ object TreeChecker {

def checkMacroGeneratedTree(original: tpd.Tree, expansion: tpd.Tree)(using Context): Unit =
if ctx.settings.XcheckMacros.value then
// We want make sure that transparent inline macros are checked in the same way that
// non transparent macros are, so we try to prepare a context which would make
// the checks behave the same way for both types of macros.
//
// E.g. Different instances of skolem types are by definition not able to be a subtype of
// one another, however in practice this is only upheld during typer phase, and we do not want
// it to be upheld during this check.
// See issue: #17009
val checkingCtx = ctx
.fresh
.setReporter(new ThrowingReporter(ctx.reporter))
.setPhase(ctx.base.inliningPhase)

val phases = ctx.base.allPhases.toList
val treeChecker = new LocalChecker(previousPhases(phases))

Expand Down
6 changes: 6 additions & 0 deletions tests/pos-macros/i17009/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import scala.quoted._

object Macro {
transparent inline def transform[T](inline expr: T): T = ${ transformImpl[T]('expr) }
def transformImpl[T: Type](f: Expr[T])(using Quotes): Expr[T] = f
}
6 changes: 6 additions & 0 deletions tests/pos-macros/i17009/Main_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def processLine(line: String): Unit = {
Macro.transform {
line.split(" ").nn
???
}
}

0 comments on commit b8fb81b

Please sign in to comment.