@@ -2,6 +2,8 @@ package dotty.tools
22package dotc
33package inlines
44
5+ import scala .collection .mutable
6+
57import dotty .tools .dotc .ast .{Trees , tpd , untpd }
68import Trees ._
79import core ._
@@ -22,14 +24,21 @@ import transform.SymUtils.*
2224import config .Printers .inlining
2325import util .Property
2426import dotty .tools .dotc .transform .TreeMapWithStages ._
27+ import dotty .tools .dotc .ast .desugar .packageObjectName
28+ import dotty .tools .dotc .core .StdNames .str
29+ import dotty .tools .dotc .util .{Spans , SrcPos }
30+ import dotty .tools .dotc .typer .TopLevelExtensionModules .newAccessorModule
2531
2632object PrepareInlineable {
2733 import tpd ._
2834
2935 private val InlineAccessorsKey = new Property .Key [InlineAccessors ]
36+ private val InlineAccessorsModuleKey = new Property .Key [mutable.Map [Symbol , Symbol ]]
3037
3138 def initContext (ctx : Context ): Context =
32- ctx.fresh.setProperty(InlineAccessorsKey , new InlineAccessors )
39+ ctx.fresh
40+ .setProperty(InlineAccessorsKey , new InlineAccessors )
41+ .setProperty(InlineAccessorsModuleKey , mutable.Map .empty)
3342
3443 def makeInlineable (tree : Tree )(using Context ): Tree =
3544 ctx.property(InlineAccessorsKey ).get.makeInlineable(tree)
@@ -39,6 +48,19 @@ object PrepareInlineable {
3948 case Some (inlineAccessors) => inlineAccessors.addAccessorDefs(cls, body)
4049 case _ => body
4150
51+ def inlineAccessorsModule (topLevelClass : Symbol )(using Context ): Symbol =
52+ assert(topLevelClass.asClass.owner.is(Package ), topLevelClass)
53+ ctx.property(InlineAccessorsModuleKey ).get.getOrElse(topLevelClass, NoSymbol )
54+
55+ def requiredInlineAccessorsModule (topLevelClass : Symbol )(using Context ): Symbol =
56+ assert(topLevelClass.asClass.owner.is(Package ), topLevelClass)
57+ ctx.property(InlineAccessorsModuleKey ) match
58+ case Some (inlineAccessorsModule) =>
59+ inlineAccessorsModule.getOrElseUpdate(
60+ topLevelClass,
61+ newAccessorModule(str.TOPLEVEL_INLINE_SUFFIX ))
62+ case None => NoSymbol
63+
4264 class InlineAccessors extends AccessProxies {
4365
4466 /** If an inline accessor name wraps a unique inline name, this is taken as indication
@@ -99,20 +121,32 @@ object PrepareInlineable {
99121 * advantage that we can re-use the receiver as is. But it is only
100122 * possible if the receiver is essentially this or an outer this, which is indicated
101123 * by the test that we can find a host for the accessor.
124+ *
125+ * @param inlineSym symbol of the inline method
126+ * @param compat use inline accessor format of 3.0-3.2
102127 */
103- class MakeInlineableDirect (inlineSym : Symbol ) extends MakeInlineableMap (inlineSym) {
128+ class MakeInlineableDirect (inlineSym : Symbol , compat : Boolean ) extends MakeInlineableMap (inlineSym) {
104129 def preTransform (tree : Tree )(using Context ): Tree = tree match {
105130 case tree : RefTree if needsAccessor(tree.symbol) =>
106131 if tree.symbol.isConstructor then
107132 report.error(" Implementation restriction: cannot use private constructors in inline methods" , tree.srcPos)
108133 tree // TODO: create a proper accessor for the private constructor
109- else
134+ else if compat then
135+ // Generate the accessor for backwards compatibility with 3.0-3.3
110136 val nearestHost = AccessProxies .hostForAccessorOf(tree.symbol)
111137 val host = if nearestHost.is(Package ) then ctx.owner.topLevelClass else nearestHost
112138 useAccessor(tree, host)
139+ else
140+ // Generate the accessor for 3.4+
141+ val nearestHost = AccessProxies .hostForAccessorOf(tree.symbol)
142+ if nearestHost.is(Package ) || (tree.symbol.owner.isStaticOwner && ! nearestHost.isStaticOwner) then
143+ useAccessor(tree, requiredInlineAccessorsModule(ctx.owner.topLevelClass))
144+ else
145+ useAccessor(tree, nearestHost)
113146 case _ =>
114147 tree
115148 }
149+
116150 override def ifNoHost (reference : RefTree )(using Context ): Tree = reference
117151 }
118152
@@ -228,8 +262,12 @@ object PrepareInlineable {
228262 // so no accessors are needed for them.
229263 tree
230264 else
265+ // Generate inline accessors for 3.0-3.3
266+ new MakeInlineablePassing (inlineSym).transform(
267+ new MakeInlineableDirect (inlineSym, compat = true ).transform(tree))
268+ // Generate and use inline accessors for 3.4+
231269 new MakeInlineablePassing (inlineSym).transform(
232- new MakeInlineableDirect (inlineSym).transform(tree))
270+ new MakeInlineableDirect (inlineSym, compat = false ).transform(tree))
233271 }
234272 }
235273
0 commit comments