Skip to content

Commit

Permalink
Merge pull request scala#13484 from dotty-staging/fix-#13476
Browse files Browse the repository at this point in the history
Do not remove accessors to early
  • Loading branch information
odersky committed Sep 22, 2021
2 parents 5e6ccc1 + 1c0bf3f commit 2784596
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 17 deletions.
3 changes: 0 additions & 3 deletions compiler/src/dotty/tools/dotc/CompilationUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 2 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/AccessProxies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/transform/Inlining.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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._
Expand Down
20 changes: 15 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/ProtectedAccessors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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))

}
15 changes: 14 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
})
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/TyperPhase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/i13476.scala
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit 2784596

Please sign in to comment.