diff --git a/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala b/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala index 23ac69d57c71..fa3c9efbfa9a 100644 --- a/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala +++ b/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala @@ -96,8 +96,8 @@ abstract class AccessProxies { /** Rewire reference to refer to `accessor` symbol */ private def rewire(reference: RefTree, accessor: Symbol)(implicit ctx: Context): Tree = { reference match { - case Select(qual, _) => qual.select(accessor) - case Ident(name) => ref(accessor) + case Select(qual, _) if qual.tpe.derivesFrom(accessor.owner) => qual.select(accessor) + case _ => ref(accessor) } }.withPos(reference.pos) @@ -161,8 +161,8 @@ object AccessProxies { def hostForAccessorOf(accessed: Symbol)(implicit ctx: Context): Symbol = { def recur(cls: Symbol): Symbol = if (!cls.exists) NoSymbol - else if (cls.derivesFrom(accessed.owner)) cls - else if (cls.companionModule.moduleClass == accessed.owner) accessed.owner + else if (cls.derivesFrom(accessed.owner) || + cls.companionModule.moduleClass == accessed.owner) cls else recur(cls.owner) recur(ctx.owner) } diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 918d85afeca6..85e9af414d60 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -17,7 +17,7 @@ object PostTyper { /** A macro transform that runs immediately after typer and that performs the following functions: * - * (1) Add super accessors and protected accessors (@see SuperAccessors) + * (1) Add super accessors (@see SuperAccessors) * * (2) Convert parameter fields that have the same name as a corresponding * public parameter field in a superclass to a forwarder to the superclass diff --git a/compiler/src/dotty/tools/dotc/typer/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala index cd55764631a6..9a0b84811f5c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala @@ -48,13 +48,16 @@ object Inliner { def accessorNameKind = InlineAccessorName /** A definition needs an accessor if it is private, protected, or qualified private - * and it is not part of the tree that gets inlined. The latter test is implemented - * by excluding all symbols properly contained in the inlined method. - */ + * and it is not part of the tree that gets inlined. The latter test is implemented + * by excluding all symbols properly contained in the inlined method. + * + * Constant vals don't need accessors since they are inlined in FirstTransform. + */ def needsAccessor(sym: Symbol)(implicit ctx: Context) = sym.isTerm && (sym.is(AccessFlags) || sym.privateWithin.exists) && - !sym.isContainedIn(inlineSym) + !sym.isContainedIn(inlineSym) && + !(sym.isStable && sym.info.widenTermRefExpr.isInstanceOf[ConstantType]) def preTransform(tree: Tree)(implicit ctx: Context): Tree @@ -124,7 +127,7 @@ object Inliner { if needsAccessor(tree.symbol) && tree.isTerm && !tree.symbol.isConstructor => val (refPart, targs, argss) = decomposeCall(tree) val qual = qualifier(refPart) - println(i"adding receiver passing inline accessor for $tree/$refPart -> (${qual.tpe}, $refPart: ${refPart.getClass}, [$targs%, %], ($argss%, %))") + inlining.println(i"adding receiver passing inline accessor for $tree/$refPart -> (${qual.tpe}, $refPart: ${refPart.getClass}, [$targs%, %], ($argss%, %))") // Need to dealias in order to cagtch all possible references to abstracted over types in // substitutions @@ -542,9 +545,10 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) { override def ensureAccessible(tpe: Type, superAccess: Boolean, pos: Position)(implicit ctx: Context): Type = { tpe match { - case tpe @ TypeRef(pre, _) if !tpe.symbol.isAccessibleFrom(pre, superAccess) => + case tpe: NamedType if !tpe.symbol.isAccessibleFrom(tpe.prefix, superAccess) => tpe.info match { case TypeAlias(alias) => return ensureAccessible(alias, superAccess, pos) + case info: ConstantType if tpe.symbol.isStable => return info case _ => } case _ => diff --git a/tests/run/i4754.check b/tests/run/i4754.check new file mode 100644 index 000000000000..7c127dc4c4c9 --- /dev/null +++ b/tests/run/i4754.check @@ -0,0 +1,3 @@ +Side effect +Side effect +12 diff --git a/tests/run/i4754.scala b/tests/run/i4754.scala new file mode 100644 index 000000000000..0907880e6499 --- /dev/null +++ b/tests/run/i4754.scala @@ -0,0 +1,16 @@ +object Foo { + private final val x = 1 + private def y = 2 + private def z: 3 = { println("Side effect"); 3 } +} + +class Foo { + import Foo._ + inline def foo = x + Foo.x + y + Foo.y + z + Foo.z +} + +object Test { + def main(args: Array[String]): Unit = { + println((new Foo).foo) + } +}