Skip to content

Commit 34ccb57

Browse files
Merge pull request #9442 from dotty-staging/support-compilation-of-StringContext
Support the compilation of Scala 2.13 StringContext
2 parents e24a0b7 + 8535594 commit 34ccb57

File tree

7 files changed

+521
-13
lines changed

7 files changed

+521
-13
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,8 @@ class Definitions {
670670
@tu lazy val ClassTagClass: ClassSymbol = requiredClass("scala.reflect.ClassTag")
671671
@tu lazy val ClassTagModule: Symbol = ClassTagClass.companionModule
672672
@tu lazy val ClassTagModule_apply: Symbol = ClassTagModule.requiredMethod(nme.apply)
673+
@tu lazy val ReflectPackageClass: Symbol = requiredPackage("scala.reflect.package").moduleClass
674+
673675

674676
@tu lazy val QuotedExprClass: ClassSymbol = requiredClass("scala.quoted.Expr")
675677
@tu lazy val QuotedExprModule: Symbol = QuotedExprClass.companionModule

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,10 @@ object SymDenotations {
914914
/** Is this a Scala 2 macro defined */
915915
final def isScala2MacroInScala3(using Context): Boolean =
916916
is(Macro, butNot = Inline) && is(Erased)
917+
// Consider the macros of StringContext as plain Scala 2 macros when
918+
// compiling the standard library with Dotty.
919+
// This should be removed on Scala 3.1
920+
&& owner.ne(defn.StringContextClass)
917921

918922
/** An erased value or an erased inline method or field */
919923
def isEffectivelyErased(using Context): Boolean =

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,11 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
148148
checkInferredWellFormed(tree.tpt)
149149
val sym = tree.symbol
150150
if sym.isScala2Macro && !ctx.settings.XignoreScala2Macros.value then
151-
if !sym.owner.unforcedDecls.exists(p => !p.isScala2Macro && p.name == sym.name && p.signature == sym.signature) then
151+
if !sym.owner.unforcedDecls.exists(p => !p.isScala2Macro && p.name == sym.name && p.signature == sym.signature)
152+
// Allow scala.reflect.materializeClassTag to be able to compile scala/reflect/package.scala
153+
// This should be removed on Scala 3.1
154+
&& sym.owner != defn.ReflectPackageClass
155+
then
152156
report.error("No Scala 3 implementation found for this Scala 2 macro.", tree.sourcePos)
153157
case _ =>
154158
processMemberDef(tree)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,21 +3222,23 @@ class Typer extends Namer
32223222
if ((inlined ne tree) && errorCount == ctx.reporter.errorCount) readaptSimplified(inlined)
32233223
else inlined
32243224
}
3225+
else if tree.symbol.name == nme.f && tree.symbol == defn.StringContext_f then
3226+
// To avoid forcing StringContext_f when compiling StingContex
3227+
// we test the name before accession symbol StringContext_f.
3228+
3229+
// As scala.StringContext.f is defined in the standard library which
3230+
// we currently do not bootstrap we cannot implement the macro in the library.
3231+
// To overcome the current limitation we intercept the call and rewrite it into
3232+
// a call to dotty.internal.StringContext.f which we can implement using the new macros.
3233+
// As the macro is implemented in the bootstrapped library, it can only be used from the bootstrapped compiler.
3234+
val Apply(TypeApply(Select(sc, _), _), args) = tree
3235+
val newCall = ref(defn.InternalStringContextMacroModule_f).appliedTo(sc).appliedToArgs(args).withSpan(tree.span)
3236+
readaptSimplified(Inliner.inlineCall(newCall))
32253237
else if (tree.symbol.isScala2Macro &&
32263238
// raw and s are eliminated by the StringInterpolatorOpt phase
32273239
tree.symbol != defn.StringContext_raw &&
32283240
tree.symbol != defn.StringContext_s)
3229-
if (tree.symbol eq defn.StringContext_f) {
3230-
// As scala.StringContext.f is defined in the standard library which
3231-
// we currently do not bootstrap we cannot implement the macro in the library.
3232-
// To overcome the current limitation we intercept the call and rewrite it into
3233-
// a call to dotty.internal.StringContext.f which we can implement using the new macros.
3234-
// As the macro is implemented in the bootstrapped library, it can only be used from the bootstrapped compiler.
3235-
val Apply(TypeApply(Select(sc, _), _), args) = tree
3236-
val newCall = ref(defn.InternalStringContextMacroModule_f).appliedTo(sc).appliedToArgs(args).withSpan(tree.span)
3237-
readaptSimplified(Inliner.inlineCall(newCall))
3238-
}
3239-
else if (ctx.settings.XignoreScala2Macros.value) {
3241+
if (ctx.settings.XignoreScala2Macros.value) {
32403242
report.warning("Scala 2 macro cannot be used in Dotty, this call will crash at runtime. See https://dotty.epfl.ch/docs/reference/dropped-features/macros.html", tree.sourcePos.startPos)
32413243
Throw(New(defn.MatchErrorClass.typeRef, Literal(Constant(s"Reached unexpanded Scala 2 macro call to ${tree.symbol.showFullName} compiled with -Xignore-scala2-macros.")) :: Nil))
32423244
.withType(tree.tpe)

0 commit comments

Comments
 (0)