Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions compiler/src/dotty/tools/dotc/CompilationUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import typer.Nullables
import transform.SymUtils._
import core.Decorators.{given _}
import config.SourceVersion
import StdNames.str

class CompilationUnit protected (val source: SourceFile) {

Expand All @@ -23,8 +24,12 @@ class CompilationUnit protected (val source: SourceFile) {

var tpdTree: tpd.Tree = tpd.EmptyTree

/** Is this the compilation unit of a Java file */
def isJava: Boolean = source.file.name.endsWith(".java")

/** Is this the compilation unit of a REPL input */
def isREPL: Boolean = source.file.name.startsWith(str.REPL_SESSION_LINE)

/** The source version for this unit, as determined by a language import */
var sourceVersion: Option[SourceVersion] = None

Expand All @@ -47,7 +52,14 @@ class CompilationUnit protected (val source: SourceFile) {

var suspended: Boolean = false

/** Can this compilation unit be suspended */
def isSuspendable: Boolean = !isREPL

/** Suspends the compilation unit by thowing a SuspendException
* and recoring the suspended compilation unit
*/
def suspend()(using Context): Nothing =
assert(isSuspendable)
if !suspended then
if (ctx.settings.XprintSuspension.value)
ctx.echo(i"suspended: $this")
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ object Splicer {
ex.getTargetException match {
case ex: scala.quoted.Reporting.StopQuotedContext =>
throw ex
case MissingClassDefinedInCurrentRun(sym) =>
case MissingClassDefinedInCurrentRun(sym) if ctx.compilationUnit.isSuspendable =>
if (ctx.settings.XprintSuspension.value)
ctx.echo(i"suspension triggered by a dependency on $sym", pos)
ctx.compilationUnit.suspend() // this throws a SuspendException
Expand Down
7 changes: 4 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1407,14 +1407,15 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
assert(level == 0)
val inlinedFrom = enclosingInlineds.last
val dependencies = macroDependencies(body)

val suspendable = ctx.compilationUnit.isSuspendable
if dependencies.nonEmpty && !ctx.reporter.errorsReported then
for sym <- dependencies do
if ctx.compilationUnit.source.file == sym.associatedFile then
ctx.error(em"Cannot call macro $sym defined in the same source file", call.sourcePos)
if (ctx.settings.XprintSuspension.value)
if (suspendable && ctx.settings.XprintSuspension.value)
ctx.echo(i"suspension triggered by macro call to ${sym.showLocated} in ${sym.associatedFile}", call.sourcePos)
ctx.compilationUnit.suspend() // this throws a SuspendException
if suspendable then
ctx.compilationUnit.suspend() // this throws a SuspendException

val evaluatedSplice = inContext(tastyreflect.MacroExpansion.context(inlinedFrom)) {
Splicer.splice(body, inlinedFrom.sourcePos, MacroClassLoader.fromContext)
Expand Down
5 changes: 5 additions & 0 deletions compiler/test-resources/repl/i9227
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
scala> import scala.quoted._; inline def myMacro[T]: Unit = ${ myMacroImpl[T] }; def myMacroImpl[T](using qctx: QuoteContext): Expr[Unit] = '{}; println(myMacro[Int])
1 | import scala.quoted._; inline def myMacro[T]: Unit = ${ myMacroImpl[T] }; def myMacroImpl[T](using qctx: QuoteContext): Expr[Unit] = '{}; println(myMacro[Int])
| ^^^^^^^^^^^^
| Cannot call macro method myMacroImpl defined in the same source file
| This location contains code that was inlined from rs$line$1:1