diff --git a/compiler/src/dotty/tools/dotc/CompilationUnit.scala b/compiler/src/dotty/tools/dotc/CompilationUnit.scala index 0feac75eef32..9b12cc9ade94 100644 --- a/compiler/src/dotty/tools/dotc/CompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/CompilationUnit.scala @@ -56,9 +56,6 @@ class CompilationUnit protected (val source: SourceFile) { */ var needsQuotePickling: Boolean = false - /** A structure containing a temporary map for generating inline accessors */ - val inlineAccessors: InlineAccessors = new InlineAccessors - var suspended: Boolean = false var suspendedAtInliningPhase: Boolean = false diff --git a/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala b/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala index 0399386a9e89..81d029e023fb 100644 --- a/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala +++ b/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala @@ -31,12 +31,9 @@ abstract class AccessProxies { */ protected def passReceiverAsArg(accessorName: Name)(using Context): Boolean = false - /** The accessor definitions that need to be added to class `cls` - * As a side-effect, this method removes entries from the `accessedBy` map. - * So a second call of the same method will yield the empty list. - */ + /** The accessor definitions that need to be added to class `cls` */ private def accessorDefs(cls: Symbol)(using Context): Iterator[DefDef] = - for (accessor <- cls.info.decls.iterator; accessed <- accessedBy.remove(accessor).toOption) yield + for accessor <- cls.info.decls.iterator; accessed <- accessedBy.get(accessor) yield DefDef(accessor.asTerm, prefss => { def numTypeParams = accessed.info match { case info: PolyType => info.paramNames.length diff --git a/compiler/src/dotty/tools/dotc/transform/Inlining.scala b/compiler/src/dotty/tools/dotc/transform/Inlining.scala index 84557a6501c1..d6bc8b117a3e 100644 --- a/compiler/src/dotty/tools/dotc/transform/Inlining.scala +++ b/compiler/src/dotty/tools/dotc/transform/Inlining.scala @@ -15,6 +15,7 @@ import SymUtils._ import NameKinds._ import dotty.tools.dotc.ast.tpd import typer.Implicits.SearchFailureType +import typer.PrepareInlineable import scala.collection.mutable import dotty.tools.dotc.core.Annotations._ diff --git a/compiler/src/dotty/tools/dotc/transform/ProtectedAccessors.scala b/compiler/src/dotty/tools/dotc/transform/ProtectedAccessors.scala index 8c59a192e09f..ccd7066e7cec 100644 --- a/compiler/src/dotty/tools/dotc/transform/ProtectedAccessors.scala +++ b/compiler/src/dotty/tools/dotc/transform/ProtectedAccessors.scala @@ -9,6 +9,7 @@ import core.Decorators._ import core.Names.TermName import MegaPhase.MiniPhase import config.Printers.transforms +import dotty.tools.dotc.util.Property /** Add accessors for all protected accesses. An accessor is needed if * according to the rules of the JVM a protected class member is not accessible @@ -50,7 +51,15 @@ class ProtectedAccessors extends MiniPhase { override def phaseName: String = ProtectedAccessors.name - object Accessors extends AccessProxies { + private val AccessorsKey = new Property.Key[Accessors] + + private def accessors(using Context): Accessors = + ctx.property(AccessorsKey).get + + override def prepareForUnit(tree: Tree)(using Context): Context = + ctx.fresh.setProperty(AccessorsKey, new Accessors) + + private class Accessors extends AccessProxies { val insert: Insert = new Insert { def accessorNameOf(name: TermName, site: Symbol)(using Context): TermName = ProtectedAccessorName(name) def needsAccessor(sym: Symbol)(using Context) = ProtectedAccessors.needsAccessor(sym) @@ -66,19 +75,20 @@ class ProtectedAccessors extends MiniPhase { } override def transformIdent(tree: Ident)(using Context): Tree = - Accessors.insert.accessorIfNeeded(tree) + accessors.insert.accessorIfNeeded(tree) override def transformSelect(tree: Select)(using Context): Tree = - Accessors.insert.accessorIfNeeded(tree) + accessors.insert.accessorIfNeeded(tree) override def transformAssign(tree: Assign)(using Context): Tree = tree.lhs match { case lhs: RefTree if lhs.name.is(ProtectedAccessorName) => - cpy.Apply(tree)(Accessors.insert.useSetter(lhs), tree.rhs :: Nil) + cpy.Apply(tree)(accessors.insert.useSetter(lhs), tree.rhs :: Nil) case _ => tree } override def transformTemplate(tree: Template)(using Context): Tree = - cpy.Template(tree)(body = Accessors.addAccessorDefs(tree.symbol.owner, tree.body)) + cpy.Template(tree)(body = accessors.addAccessorDefs(tree.symbol.owner, tree.body)) + } diff --git a/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala b/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala index e6ab882e7698..8fea810921e4 100644 --- a/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala +++ b/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala @@ -26,6 +26,19 @@ import dotty.tools.dotc.transform.TreeMapWithStages._ object PrepareInlineable { import tpd._ + private val InlineAccessorsKey = new Property.Key[InlineAccessors] + + def initContext(ctx: Context): Context = + ctx.fresh.setProperty(InlineAccessorsKey, new InlineAccessors) + + def makeInlineable(tree: Tree)(using Context): Tree = + ctx.property(InlineAccessorsKey).get.makeInlineable(tree) + + def addAccessorDefs(cls: Symbol, body: List[Tree])(using Context): List[Tree] = + ctx.property(InlineAccessorsKey) match + case Some(inlineAccessors) => inlineAccessors.addAccessorDefs(cls, body) + case _ => body + class InlineAccessors extends AccessProxies { /** If an inline accessor name wraps a unique inline name, this is taken as indication @@ -251,7 +264,7 @@ object PrepareInlineable { if inlined.isInlineMethod then inlinedBody = dropInlineIfError(inlined, checkInlineMethod(inlined, - ctx.compilationUnit.inlineAccessors.makeInlineable(inlinedBody))) + PrepareInlineable.makeInlineable(inlinedBody))) inlining.println(i"Body to inline for $inlined: $inlinedBody") inlinedBody }) diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 9c60374d9a9a..0d9186a0fb5f 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -70,7 +70,7 @@ trait QuotesAndSplices { } private def makeInlineable(tree: Tree)(using Context): Tree = - ctx.compilationUnit.inlineAccessors.makeInlineable(tree) + PrepareInlineable.makeInlineable(tree) /** Translate `${ t: Expr[T] }` into expression `t.splice` while tracking the quotation level in the context */ def typedSplice(tree: untpd.Splice, pt: Type)(using Context): Tree = { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index b77c21893ef7..b7741c636b06 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2461,7 +2461,7 @@ class Typer extends Namer // 4. Polymorphic type defs override nothing. protected def addAccessorDefs(cls: Symbol, body: List[Tree])(using Context): List[Tree] = - ctx.compilationUnit.inlineAccessors.addAccessorDefs(cls, body) + PrepareInlineable.addAccessorDefs(cls, body) /** If this is a real class, make sure its first parent is a * constructor call. Cannot simply use a type. Overridden in ReTyper. diff --git a/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala b/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala index 8141bfabc3fb..bb1bfbea28e5 100644 --- a/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala +++ b/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala @@ -81,7 +81,8 @@ class TyperPhase(addRootImports: Boolean = true) extends Phase { override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] = val unitContexts = for unit <- units yield - val newCtx = ctx.fresh.setPhase(this.start).setCompilationUnit(unit) + val newCtx0 = ctx.fresh.setPhase(this.start).setCompilationUnit(unit) + val newCtx = PrepareInlineable.initContext(newCtx0) report.inform(s"typing ${unit.source}") if (addRootImports) newCtx.withRootImports diff --git a/tests/pos/i13476.scala b/tests/pos/i13476.scala new file mode 100644 index 000000000000..e1810d9cfe33 --- /dev/null +++ b/tests/pos/i13476.scala @@ -0,0 +1,7 @@ +private object Foo: + inline def d(arg : Int): Unit = {} + transparent inline def haha() : Unit = {} + +export Foo.* + +@main def main : Unit = haha()