@@ -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,18 +121,33 @@ 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) {
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
109134 }
110- else useAccessor(tree)
135+ else if compat then
136+ // Generate the accessor for backwards compatibility with 3.0-3.3
137+ val nearestHost = AccessProxies .hostForAccessorOf(tree.symbol)
138+ val host = if nearestHost.is(Package ) then ctx.owner.topLevelClass else nearestHost
139+ useAccessor(tree, host)
140+ else
141+ // Generate the accessor for 3.4+
142+ val nearestHost = AccessProxies .hostForAccessorOf(tree.symbol)
143+ if nearestHost.is(Package ) || (tree.symbol.owner.isStaticOwner && ! nearestHost.isStaticOwner) then
144+ useAccessor(tree, requiredInlineAccessorsModule(ctx.owner.topLevelClass))
145+ else
146+ useAccessor(tree, nearestHost)
111147 case _ =>
112148 tree
113149 }
150+
114151 override def ifNoHost (reference : RefTree )(using Context ): Tree = reference
115152 }
116153
@@ -226,8 +263,12 @@ object PrepareInlineable {
226263 // so no accessors are needed for them.
227264 tree
228265 else
266+ // Generate inline accessors for 3.0-3.3
267+ new MakeInlineablePassing (inlineSym).transform(
268+ new MakeInlineableDirect (inlineSym, compat = true ).transform(tree))
269+ // Generate and use inline accessors for 3.4+
229270 new MakeInlineablePassing (inlineSym).transform(
230- new MakeInlineableDirect (inlineSym).transform(tree))
271+ new MakeInlineableDirect (inlineSym, compat = false ).transform(tree))
231272 }
232273 }
233274
0 commit comments