Skip to content

Commit b50e376

Browse files
committed
Eliminate macros in RefChecks
... after checking that they do not override anything. This means we do not need to transform their bodies in ReifyQuotes.
1 parent 36b87fd commit b50e376

File tree

5 files changed

+31
-16
lines changed

5 files changed

+31
-16
lines changed

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

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

601+
/** A Scala 2 Macro */
602+
final val Scala2Macro = allOf(Macro, Scala2x)
603+
601604
/** A trait that does not need to be initialized */
602605
final val NoInitsTrait = allOf(Trait, NoInits)
603606

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import NameKinds.OuterSelectName
1616
import scala.collection.mutable
1717

1818
// TODO
19-
// check that inline methods override nothing
20-
// drop inline methods
2119
// adapt to Expr/Type when passing arguments to splices
2220

2321
/** Translates quoted terms and types to `unpickle` method calls.
@@ -175,12 +173,9 @@ class ReifyQuotes extends MacroTransform {
175173
case _ =>
176174
}
177175

178-
/** Are we in the body of an inline method? */
179-
def inInline(implicit ctx: Context) = ctx.owner.ownersIterator.exists(_.isInlineMethod)
180-
181176
/** Issue a "splice outside quote" error unless we ar in the body of an inline method */
182177
def spliceOutsideQuotes(pos: Position)(implicit ctx: Context) =
183-
if (!inInline) ctx.error(i"splice outside quotes", pos)
178+
ctx.error(i"splice outside quotes", pos)
184179

185180
/** Check reference to `sym` for phase consistency, where `tp` is the underlying type
186181
* by which we refer to `sym`.
@@ -193,8 +188,7 @@ class ReifyQuotes extends MacroTransform {
193188
else i"${sym.name}.this"
194189
if (!isThis && sym.maybeOwner.isType)
195190
check(sym.owner, sym.owner.thisType, pos)
196-
else if (sym.exists && !sym.isStaticOwner && !inInline &&
197-
levelOf.getOrElse(sym, level) != level)
191+
else if (sym.exists && !sym.isStaticOwner && levelOf.getOrElse(sym, level) != level)
198192
tp match {
199193
case tp: TypeRef =>
200194
importedTypes += tp
@@ -288,8 +282,7 @@ class ReifyQuotes extends MacroTransform {
288282
}
289283
else {
290284
spliceOutsideQuotes(splice.pos)
291-
if (splice.isType) TypeTree(splice.tpe.dealias)
292-
else transform(body).select(defn.QuotedExpr_run)
285+
splice
293286
}
294287
}.withPos(splice.pos)
295288

@@ -336,6 +329,8 @@ class ReifyQuotes extends MacroTransform {
336329
cpy.Select(expansion)(cpy.Inlined(tree)(call, bindings, body), name)
337330
case _: Import =>
338331
tree
332+
case tree: DefDef if tree.symbol.is(Macro) =>
333+
cpy.DefDef(tree)(rhs = EmptyTree)
339334
case _ =>
340335
markDef(tree)
341336
checkLevel(mapOverTree(enteredSyms))

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,8 @@ class TreeChecker extends Phase with SymTransformer {
375375
def isNonMagicalMethod(x: Symbol) =
376376
x.is(Method) &&
377377
!x.isCompanionMethod &&
378-
!x.isValueClassConvertMethod
378+
!x.isValueClassConvertMethod &&
379+
!(x.is(Macro) && ctx.phase.refChecked)
379380

380381
val symbolsNotDefined = cls.classInfo.decls.toList.toSet.filter(isNonMagicalMethod) -- impl.body.map(_.symbol) - constr.symbol
381382

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ object RefChecks {
130130
* That is for overriding member M and overridden member O:
131131
*
132132
* 1.1. M must have the same or stronger access privileges as O.
133-
* 1.2. O must not be final.
133+
* 1.2. O must not be effectively final.
134134
* 1.3. O is deferred, or M has `override` modifier.
135135
* 1.4. If O is stable, then so is M.
136136
* // @M: LIFTED 1.5. Neither M nor O are a parameterized type alias
@@ -144,8 +144,9 @@ object RefChecks {
144144
* 1.8.1 M's type is a subtype of O's type, or
145145
* 1.8.2 M is of type []S, O is of type ()T and S <: T, or
146146
* 1.8.3 M is of type ()S, O is of type []T and S <: T, or
147-
* 1.9. If M is a macro def, O cannot be deferred unless there's a concrete method overriding O.
148-
* 1.10. If M is not a macro def, O cannot be a macro def.
147+
* 1.9 M must not be a Dotty macro def
148+
* 1.10. If M is a 2.x macro def, O cannot be deferred unless there's a concrete method overriding O.
149+
* 1.11. If M is not a macro def, O cannot be a macro def.
149150
* 2. Check that only abstract classes have deferred members
150151
* 3. Check that concrete classes do not have deferred definitions
151152
* that are not implemented in a subclass.
@@ -372,9 +373,11 @@ object RefChecks {
372373
overrideError("may not override a non-lazy value")
373374
} else if (other.is(Lazy) && !other.isRealMethod && !member.is(Lazy)) {
374375
overrideError("must be declared lazy to override a lazy value")
375-
} else if (other.is(Deferred) && member.is(Macro) && member.extendedOverriddenSymbols.forall(_.is(Deferred))) { // (1.9)
376+
} else if (member.is(Macro, butNot = Scala2x)) { // (1.9)
377+
overrideError("is a macro, may not override anything")
378+
} else if (other.is(Deferred) && member.is(Scala2Macro) && member.extendedOverriddenSymbols.forall(_.is(Deferred))) { // (1.10)
376379
overrideError("cannot be used here - term macros cannot override abstract methods")
377-
} else if (other.is(Macro) && !member.is(Macro)) { // (1.10)
380+
} else if (other.is(Macro) && !member.is(Macro)) { // (1.11)
378381
overrideError("cannot be used here - only term macros can override term macros")
379382
} else if (!compatibleTypes(memberTp(self), otherTp(self)) &&
380383
!compatibleTypes(memberTp(upwardsSelf), otherTp(upwardsSelf))) {

tests/neg/quotedMacroOverride.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
object Test {
2+
3+
abstract class A {
4+
def f(): Unit
5+
inline def g(): Unit = ()
6+
}
7+
8+
class B extends A {
9+
inline def f() = ~('()) // error: may not override
10+
override def g() = () // error: may not override
11+
}
12+
13+
}

0 commit comments

Comments
 (0)