Skip to content

Commit

Permalink
Fix treatment of separately compiled @Native methods in FirstTransform
Browse files Browse the repository at this point in the history
We need to use a SymTransformer, fixing the method in the tree is not enough.

[Cherry-picked 066101a]
  • Loading branch information
odersky authored and WojciechMazur committed Dec 3, 2024
1 parent 0484e65 commit a08f4c1
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 11 deletions.
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ object Flags {
val ConstructorProxyModule: FlagSet = ConstructorProxy | Module
val DefaultParameter: FlagSet = HasDefault | Param // A Scala 2x default parameter
val DeferredInline: FlagSet = Deferred | Inline
val DeferredMethod: FlagSet = Deferred | Method
val DeferredOrLazy: FlagSet = Deferred | Lazy
val DeferredOrLazyOrMethod: FlagSet = Deferred | Lazy | Method
val DeferredOrTermParamOrAccessor: FlagSet = Deferred | ParamAccessor | TermParam // term symbols without right-hand sides
Expand Down
26 changes: 15 additions & 11 deletions compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Decorators.*
import scala.collection.mutable
import DenotTransformers.*
import NameOps.*
import SymDenotations.SymDenotation
import NameKinds.OuterSelectName
import StdNames.*
import config.Feature
Expand All @@ -35,22 +36,26 @@ object FirstTransform {
* if (true) A else B ==> A
* if (false) A else B ==> B
*/
class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
class FirstTransform extends MiniPhase with SymTransformer { thisPhase =>
import ast.tpd.*

override def phaseName: String = FirstTransform.name

override def description: String = FirstTransform.description

/** eliminate self symbol in ClassInfo */
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type = tp match {
case tp @ ClassInfo(_, _, _, _, self: Symbol) =>
tp.derivedClassInfo(selfInfo = self.info)
case _ =>
tp
}

override protected def infoMayChange(sym: Symbol)(using Context): Boolean = sym.isClass
/** eliminate self symbol in ClassInfo, reset Deferred for @native methods */
override def transformSym(sym: SymDenotation)(using Context): SymDenotation =
if sym.isClass then
sym.info match
case tp @ ClassInfo(_, _, _, _, self: Symbol) =>
val info1 = tp.derivedClassInfo(selfInfo = self.info)
sym.copySymDenotation(info = info1).copyCaches(sym, ctx.phase.next)
case _ =>
sym
else if sym.isAllOf(DeferredMethod) && sym.hasAnnotation(defn.NativeAnnot) then
sym.copySymDenotation(initFlags = sym.flags &~ Deferred)
else
sym

override def checkPostCondition(tree: Tree)(using Context): Unit =
tree match {
Expand Down Expand Up @@ -121,7 +126,6 @@ class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
override def transformDefDef(ddef: DefDef)(using Context): Tree =
val meth = ddef.symbol.asTerm
if meth.hasAnnotation(defn.NativeAnnot) then
meth.resetFlag(Deferred)
DefDef(meth, _ =>
ref(defn.Sys_error.termRef).withSpan(ddef.span)
.appliedTo(Literal(Constant(s"native method stub"))))
Expand Down
1 change: 1 addition & 0 deletions tests/pos/i20588/Baz_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Baz extends Foo
3 changes: 3 additions & 0 deletions tests/pos/i20588/Foo_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Foo {
@native def test(): Unit
}

0 comments on commit a08f4c1

Please sign in to comment.