Skip to content

Commit e94a2e1

Browse files
authored
Merge pull request #4760 from dotty-staging/fix-4754
Fix #4754: Don't generate inline accessor for constants
2 parents 61840b6 + 95d3b43 commit e94a2e1

File tree

5 files changed

+34
-11
lines changed

5 files changed

+34
-11
lines changed

compiler/src/dotty/tools/dotc/transform/AccessProxies.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ abstract class AccessProxies {
9696
/** Rewire reference to refer to `accessor` symbol */
9797
private def rewire(reference: RefTree, accessor: Symbol)(implicit ctx: Context): Tree = {
9898
reference match {
99-
case Select(qual, _) => qual.select(accessor)
100-
case Ident(name) => ref(accessor)
99+
case Select(qual, _) if qual.tpe.derivesFrom(accessor.owner) => qual.select(accessor)
100+
case _ => ref(accessor)
101101
}
102102
}.withPos(reference.pos)
103103

@@ -161,8 +161,8 @@ object AccessProxies {
161161
def hostForAccessorOf(accessed: Symbol)(implicit ctx: Context): Symbol = {
162162
def recur(cls: Symbol): Symbol =
163163
if (!cls.exists) NoSymbol
164-
else if (cls.derivesFrom(accessed.owner)) cls
165-
else if (cls.companionModule.moduleClass == accessed.owner) accessed.owner
164+
else if (cls.derivesFrom(accessed.owner) ||
165+
cls.companionModule.moduleClass == accessed.owner) cls
166166
else recur(cls.owner)
167167
recur(ctx.owner)
168168
}

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object PostTyper {
1717

1818
/** A macro transform that runs immediately after typer and that performs the following functions:
1919
*
20-
* (1) Add super accessors and protected accessors (@see SuperAccessors)
20+
* (1) Add super accessors (@see SuperAccessors)
2121
*
2222
* (2) Convert parameter fields that have the same name as a corresponding
2323
* public parameter field in a superclass to a forwarder to the superclass

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,16 @@ object Inliner {
4848
def accessorNameKind = InlineAccessorName
4949

5050
/** A definition needs an accessor if it is private, protected, or qualified private
51-
* and it is not part of the tree that gets inlined. The latter test is implemented
52-
* by excluding all symbols properly contained in the inlined method.
53-
*/
51+
* and it is not part of the tree that gets inlined. The latter test is implemented
52+
* by excluding all symbols properly contained in the inlined method.
53+
*
54+
* Constant vals don't need accessors since they are inlined in FirstTransform.
55+
*/
5456
def needsAccessor(sym: Symbol)(implicit ctx: Context) =
5557
sym.isTerm &&
5658
(sym.is(AccessFlags) || sym.privateWithin.exists) &&
57-
!sym.isContainedIn(inlineSym)
59+
!sym.isContainedIn(inlineSym) &&
60+
!(sym.isStable && sym.info.widenTermRefExpr.isInstanceOf[ConstantType])
5861

5962
def preTransform(tree: Tree)(implicit ctx: Context): Tree
6063

@@ -124,7 +127,7 @@ object Inliner {
124127
if needsAccessor(tree.symbol) && tree.isTerm && !tree.symbol.isConstructor =>
125128
val (refPart, targs, argss) = decomposeCall(tree)
126129
val qual = qualifier(refPart)
127-
println(i"adding receiver passing inline accessor for $tree/$refPart -> (${qual.tpe}, $refPart: ${refPart.getClass}, [$targs%, %], ($argss%, %))")
130+
inlining.println(i"adding receiver passing inline accessor for $tree/$refPart -> (${qual.tpe}, $refPart: ${refPart.getClass}, [$targs%, %], ($argss%, %))")
128131

129132
// Need to dealias in order to cagtch all possible references to abstracted over types in
130133
// substitutions
@@ -542,9 +545,10 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
542545

543546
override def ensureAccessible(tpe: Type, superAccess: Boolean, pos: Position)(implicit ctx: Context): Type = {
544547
tpe match {
545-
case tpe @ TypeRef(pre, _) if !tpe.symbol.isAccessibleFrom(pre, superAccess) =>
548+
case tpe: NamedType if !tpe.symbol.isAccessibleFrom(tpe.prefix, superAccess) =>
546549
tpe.info match {
547550
case TypeAlias(alias) => return ensureAccessible(alias, superAccess, pos)
551+
case info: ConstantType if tpe.symbol.isStable => return info
548552
case _ =>
549553
}
550554
case _ =>

tests/run/i4754.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Side effect
2+
Side effect
3+
12

tests/run/i4754.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
object Foo {
2+
private final val x = 1
3+
private def y = 2
4+
private def z: 3 = { println("Side effect"); 3 }
5+
}
6+
7+
class Foo {
8+
import Foo._
9+
inline def foo = x + Foo.x + y + Foo.y + z + Foo.z
10+
}
11+
12+
object Test {
13+
def main(args: Array[String]): Unit = {
14+
println((new Foo).foo)
15+
}
16+
}

0 commit comments

Comments
 (0)