Skip to content

Commit 066101a

Browse files
committed
Fix treatment of separately compiled @Native methods in FirstTransform
We need to use a SymTransformer, fixing the method in the tree is not enough.
1 parent eb42a4d commit 066101a

File tree

4 files changed

+20
-11
lines changed

4 files changed

+20
-11
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ object Flags {
569569
val ConstructorProxyModule: FlagSet = ConstructorProxy | Module
570570
val DefaultParameter: FlagSet = HasDefault | Param // A Scala 2x default parameter
571571
val DeferredInline: FlagSet = Deferred | Inline
572+
val DeferredMethod: FlagSet = Deferred | Method
572573
val DeferredOrLazy: FlagSet = Deferred | Lazy
573574
val DeferredOrLazyOrMethod: FlagSet = Deferred | Lazy | Method
574575
val DeferredOrTermParamOrAccessor: FlagSet = Deferred | ParamAccessor | TermParam // term symbols without right-hand sides

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

+15-11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Decorators.*
1414
import scala.collection.mutable
1515
import DenotTransformers.*
1616
import NameOps.*
17+
import SymDenotations.SymDenotation
1718
import NameKinds.OuterSelectName
1819
import StdNames.*
1920
import config.Feature
@@ -35,22 +36,26 @@ object FirstTransform {
3536
* if (true) A else B ==> A
3637
* if (false) A else B ==> B
3738
*/
38-
class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
39+
class FirstTransform extends MiniPhase with SymTransformer { thisPhase =>
3940
import ast.tpd.*
4041

4142
override def phaseName: String = FirstTransform.name
4243

4344
override def description: String = FirstTransform.description
4445

45-
/** eliminate self symbol in ClassInfo */
46-
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type = tp match {
47-
case tp @ ClassInfo(_, _, _, _, self: Symbol) =>
48-
tp.derivedClassInfo(selfInfo = self.info)
49-
case _ =>
50-
tp
51-
}
52-
53-
override protected def infoMayChange(sym: Symbol)(using Context): Boolean = sym.isClass
46+
/** eliminate self symbol in ClassInfo, reset Deferred for @native methods */
47+
override def transformSym(sym: SymDenotation)(using Context): SymDenotation =
48+
if sym.isClass then
49+
sym.info match
50+
case tp @ ClassInfo(_, _, _, _, self: Symbol) =>
51+
val info1 = tp.derivedClassInfo(selfInfo = self.info)
52+
sym.copySymDenotation(info = info1).copyCaches(sym, ctx.phase.next)
53+
case _ =>
54+
sym
55+
else if sym.isAllOf(DeferredMethod) && sym.hasAnnotation(defn.NativeAnnot) then
56+
sym.copySymDenotation(initFlags = sym.flags &~ Deferred)
57+
else
58+
sym
5459

5560
override def checkPostCondition(tree: Tree)(using Context): Unit =
5661
tree match {
@@ -121,7 +126,6 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
121126
override def transformDefDef(ddef: DefDef)(using Context): Tree =
122127
val meth = ddef.symbol.asTerm
123128
if meth.hasAnnotation(defn.NativeAnnot) then
124-
meth.resetFlag(Deferred)
125129
DefDef(meth, _ =>
126130
ref(defn.Sys_error.termRef).withSpan(ddef.span)
127131
.appliedTo(Literal(Constant(s"native method stub"))))

tests/pos/i20588/Baz_2.scala

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
class Baz extends Foo

tests/pos/i20588/Foo_1.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class Foo {
2+
@native def test(): Unit
3+
}

0 commit comments

Comments
 (0)