Skip to content

Commit 54fb992

Browse files
Merge pull request #6179 from dotty-staging/fix-#6150
Fix #6150: Emit error when calling Scala 2 macro
2 parents aa59bef + 89412a0 commit 54fb992

File tree

18 files changed

+97
-18
lines changed

18 files changed

+97
-18
lines changed

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class ScalaSettings extends Settings.SettingGroup {
7777
val XreplLineWidth: Setting[Int] = IntSetting("-Xrepl-line-width", "Maximal number of columns per line for REPL output", 390)
7878
val XfatalWarnings: Setting[Boolean] = BooleanSetting("-Xfatal-warnings", "Fail the compilation if there are any warnings.")
7979
val XverifySignatures: Setting[Boolean] = BooleanSetting("-Xverify-signatures", "Verify generic signatures in generated bytecode.")
80+
val XignoreScala2Macros: Setting[Boolean] = BooleanSetting("-Xignore-scala2-macros", "Ignore errors when compiling code that calls Scala2 macros, these will fail at runtime.")
8081

8182
val XmixinForceForwarders = ChoiceSetting(
8283
name = "-Xmixin-force-forwarders",

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,10 +631,17 @@ class Definitions {
631631
def StringContextS(implicit ctx: Context): Symbol = StringContextSR.symbol
632632
lazy val StringContextRawR: TermRef = StringContextClass.requiredMethodRef(nme.raw_)
633633
def StringContextRaw(implicit ctx: Context): Symbol = StringContextRawR.symbol
634+
lazy val StringContext_fR: TermRef = StringContextClass.requiredMethodRef(nme.f)
635+
def StringContext_f(implicit ctx: Context): Symbol = StringContext_fR.symbol
634636
def StringContextModule(implicit ctx: Context): Symbol = StringContextClass.companionModule
635637
lazy val StringContextModule_applyR: TermRef = StringContextModule.requiredMethodRef(nme.apply)
636638
def StringContextModule_apply(implicit ctx: Context): Symbol = StringContextModule_applyR.symbol
637639

640+
lazy val InternalStringContextModuleR: TermRef = ctx.requiredModuleRef("dotty.internal.StringContext")
641+
def InternalStringContextModule(implicit ctx: Context): Symbol = InternalStringContextModuleR.termSymbol
642+
lazy val InternalStringContextModule_fR: TermRef = InternalStringContextModule.requiredMethodRef(nme.f)
643+
def InternalStringContextModule_f(implicit ctx: Context): Symbol = InternalStringContextModule_fR.symbol
644+
638645
lazy val PartialFunctionType: TypeRef = ctx.requiredClassRef("scala.PartialFunction")
639646
def PartialFunctionClass(implicit ctx: Context): ClassSymbol = PartialFunctionType.symbol.asClass
640647
lazy val PartialFunction_isDefinedAtR: TermRef = PartialFunctionClass.requiredMethodRef(nme.isDefinedAt)

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,6 @@ object Flags {
661661
/** Is a default parameter in Scala 2*/
662662
final val DefaultParameter: FlagConjunction = allOf(Param, DefaultParameterized)
663663

664-
/** A Scala 2 Macro */
665-
final val Scala2Macro: FlagConjunction = allOf(Macro, Scala2x)
666-
667664
/** A trait that does not need to be initialized */
668665
final val NoInitsTrait: FlagConjunction = allOf(Trait, NoInits)
669666

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,9 @@ object SymDenotations {
807807
// we need an inline flag on them only do that
808808
// reduceProjection gets access to their rhs
809809

810+
/** Is this a Scala 2 macro */
811+
final def isScala2Macro(implicit ctx: Context): Boolean = is(Macro) && symbol.owner.is(Scala2x)
812+
810813
/** An erased value or an inline method, excluding @forceInline annotated methods.
811814
* The latter have to be kept around to get to parity with Scala.
812815
* This is necessary at least until we have full bootstrap. Right now

compiler/src/dotty/tools/dotc/profile/Profiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ object ConsoleProfileReporter extends ProfileReporter {
228228
}
229229

230230
override def reportGc(data: GcEventData): Unit = {
231-
println(f"Profiler GC reported ${data.gcEndMillis - data.gcStartMillis}ms")
231+
println(s"Profiler GC reported ${data.gcEndMillis - data.gcStartMillis}ms")
232232
}
233233
}
234234

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,10 @@ object RefChecks {
400400
overrideError("is an extension method, cannot override a normal method")
401401
} else if (other.is(Extension) && !member.is(Extension)) { // (1.9.2)
402402
overrideError("is a normal method, cannot override an extension method")
403-
} else if ((member.isInlineMethod || member.is(Scala2Macro)) && other.is(Deferred) &&
403+
} else if ((member.isInlineMethod || member.isScala2Macro) && other.is(Deferred) &&
404404
member.extendedOverriddenSymbols.forall(_.is(Deferred))) { // (1.10)
405405
overrideError("is an inline method, must override at least one concrete method")
406-
} else if (other.is(Scala2Macro) && !member.is(Scala2Macro)) { // (1.11)
406+
} else if (other.isScala2Macro && !member.isScala2Macro) { // (1.11)
407407
overrideError("cannot be used here - only Scala-2 macros can override Scala-2 macros")
408408
} else if (!compatibleTypes(memberTp(self), otherTp(self)) &&
409409
!compatibleTypes(memberTp(upwardsSelf), otherTp(upwardsSelf))) {

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2756,6 +2756,24 @@ class Typer extends Namer
27562756
tree.tpe <:< wildApprox(pt)
27572757
readaptSimplified(Inliner.inlineCall(tree, pt))
27582758
}
2759+
else if (tree.symbol.isScala2Macro) {
2760+
if (ctx.settings.XignoreScala2Macros.value) {
2761+
ctx.warning("Scala 2 macro cannot be used in Dotty, this call will crash at runtime. See http://dotty.epfl.ch/docs/reference/dropped-features/macros.html", tree.sourcePos)
2762+
tree
2763+
} else if (tree.symbol eq defn.StringContext_f) {
2764+
// As scala.StringContext.f is defined in the standard library which
2765+
// we currently do not bootstrap we cannot implement the macro the library.
2766+
// To overcome the current limitation we intercept the call and rewrite it into
2767+
// a call to dotty.internal.StringContext.f which we can implement using the new macros.
2768+
// As the macro is implemented in the bootstrapped library, it can only be used from the bootstrapped compiler.
2769+
val Apply(TypeApply(Select(sc, _), _), args) = tree
2770+
val newCall = ref(defn.InternalStringContextModule_f).appliedTo(sc).appliedToArgs(args)
2771+
Inliner.inlineCall(newCall, pt)
2772+
} else {
2773+
ctx.error("Scala 2 macro cannot be used in Dotty. See http://dotty.epfl.ch/docs/reference/dropped-features/macros.html", tree.sourcePos)
2774+
tree
2775+
}
2776+
}
27592777
else if (tree.tpe <:< pt) {
27602778
if (pt.hasAnnotation(defn.InlineParamAnnot))
27612779
checkInlineConformant(tree, isFinal = false, "argument to inline parameter")

compiler/test/dotty/tools/backend/jvm/AsmNode.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ sealed trait AsmNode[+T] {
1515
def attrs: List[Attribute]
1616
def visibleAnnotations: List[AnnotationNode]
1717
def invisibleAnnotations: List[AnnotationNode]
18-
def characteristics = f"$name%15s $desc%-30s$accessString$sigString"
19-
def erasedCharacteristics = f"$name%15s $desc%-30s$accessString"
18+
def characteristics = "%15s %-30s%s%s".format(name, desc, accessString, sigString)
19+
def erasedCharacteristics = "%15s %-30s%s".format(name, desc, accessString)
2020

2121
private def accessString = if (access == 0) "" else " " + Modifier.toString(access)
2222
private def sigString = if (signature == null) "" else " " + signature

0 commit comments

Comments
 (0)