Skip to content

Various fixes related to inlining #4464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ class TreePickler(pickler: TastyPickler) {
if (flags is DefaultParameterized) writeByte(DEFAULTparameterized)
if (flags is Stable) writeByte(STABLE)
if ((flags is ParamAccessor) && sym.isSetter) writeByte(PARAMsetter)
if ((flags is Label)) writeByte(LABEL)
} else {
if (flags is Sealed) writeByte(SEALED)
if (flags is Abstract) writeByte(ABSTRACT)
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ class TreeUnpickler(reader: TastyReader,

def readRhs(implicit ctx: Context) =
if (noRhs(end)) EmptyTree
else readLater(end, rdr => ctx => rdr.readTerm()(ctx))
else readLater(end, rdr => ctx => rdr.readTerm()(ctx.retractMode(Mode.InSuperCall)))

def ValDef(tpt: Tree) =
ta.assignType(untpd.ValDef(sym.name.asTermName, tpt, readRhs(localCtx)), sym)
Expand Down Expand Up @@ -1135,7 +1135,7 @@ class TreeUnpickler(reader: TastyReader,
def readLater[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Trees.Lazy[T] = {
val localReader = fork
goto(end)
new LazyReader(localReader, ctx.owner, op)
new LazyReader(localReader, ctx.owner, ctx.mode, op)
}

def readHole(end: Addr, isType: Boolean)(implicit ctx: Context): Tree = {
Expand Down Expand Up @@ -1182,10 +1182,10 @@ class TreeUnpickler(reader: TastyReader,
}
}

class LazyReader[T <: AnyRef](reader: TreeReader, owner: Symbol, op: TreeReader => Context => T) extends Trees.Lazy[T] {
class LazyReader[T <: AnyRef](reader: TreeReader, owner: Symbol, mode: Mode, op: TreeReader => Context => T) extends Trees.Lazy[T] {
def complete(implicit ctx: Context): T = {
pickling.println(i"starting to read at ${reader.reader.currentAddr} with owner $owner")
op(reader)(ctx.withPhaseNoLater(ctx.picklerPhase).withOwner(owner))
op(reader)(ctx.withPhaseNoLater(ctx.picklerPhase).withOwner(owner).withModeBits(mode))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) {

override protected def templateText(tree: TypeDef, impl: Template): Text = {
val decl =
if (!tree.mods.is(Module)) modText(tree.mods, keywordStr(if ((tree).mods is Trait) "trait" else "class"))
else modText(tree.mods &~ (Final | Module), keywordStr("object"))
if (!tree.mods.is(Module)) modText(tree.mods, tree.symbol, keywordStr(if ((tree).mods is Trait) "trait" else "class"))
else modText(tree.mods, tree.symbol, keywordStr("object"), suppress = Final | Module)
decl ~~ typeText(nameIdText(tree)) ~ withEnclosingDef(tree) { toTextTemplate(impl) } ~ ""
}

Expand Down
28 changes: 15 additions & 13 deletions compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case tree @ TypeDef(name, rhs) =>
def typeDefText(tparamsText: => Text, rhsText: => Text) =
dclTextOr(tree) {
modText(tree.mods, keywordStr("type")) ~~ (varianceText(tree.mods) ~ typeText(nameIdText(tree))) ~
modText(tree.mods, tree.symbol, keywordStr("type")) ~~ (varianceText(tree.mods) ~ typeText(nameIdText(tree))) ~
withEnclosingDef(tree) { tparamsText ~ rhsText }
}
def recur(rhs: Tree, tparamsTxt: => Text): Text = rhs match {
Expand Down Expand Up @@ -449,7 +449,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
toText(t)
case tree @ ModuleDef(name, impl) =>
withEnclosingDef(tree) {
modText(tree.mods, keywordStr("object")) ~~ nameIdText(tree) ~ toTextTemplate(impl)
modText(tree.mods, NoSymbol, keywordStr("object")) ~~ nameIdText(tree) ~ toTextTemplate(impl)
}
case SymbolLit(str) =>
"'" + str
Expand Down Expand Up @@ -506,7 +506,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
t ~ cxBoundToText(cxb)
}
case PatDef(mods, pats, tpt, rhs) =>
modText(mods, keywordStr("val")) ~~ toText(pats, ", ") ~ optAscription(tpt) ~
modText(mods, NoSymbol, keywordStr("val")) ~~ toText(pats, ", ") ~ optAscription(tpt) ~
optText(rhs)(" = " ~ _)
case ParsedTry(expr, handler, finalizer) =>
changePrec(GlobalPrec) {
Expand Down Expand Up @@ -618,7 +618,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
protected def valDefToText[T >: Untyped](tree: ValDef[T]): Text = {
import untpd.{modsDeco => _, _}
dclTextOr(tree) {
modText(tree.mods, keywordStr(if (tree.mods is Mutable) "var" else "val")) ~~
modText(tree.mods, tree.symbol, keywordStr(if (tree.mods is Mutable) "var" else "val")) ~~
valDefText(nameIdText(tree)) ~ optAscription(tree.tpt) ~
withEnclosingDef(tree) { optText(tree.rhs)(" = " ~ _) }
}
Expand All @@ -627,7 +627,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
protected def defDefToText[T >: Untyped](tree: DefDef[T]): Text = {
import untpd.{modsDeco => _, _}
dclTextOr(tree) {
val prefix = modText(tree.mods, keywordStr("def")) ~~ valDefText(nameIdText(tree))
val prefix = modText(tree.mods, tree.symbol, keywordStr("def")) ~~ valDefText(nameIdText(tree))
withEnclosingDef(tree) {
addVparamssText(prefix ~ tparamsText(tree.tparams), tree.vparamss) ~ optAscription(tree.tpt) ~
optText(tree.rhs)(" = " ~ _)
Expand All @@ -642,7 +642,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
val prefix: Text =
if (vparamss.isEmpty || primaryConstrs.nonEmpty) tparamsTxt
else {
var modsText = modText(constr.mods, "")
var modsText = modText(constr.mods, constr.symbol, "")
if (!modsText.isEmpty) modsText = " " ~ modsText
if (constr.mods.hasAnnotations && !constr.mods.hasFlags) modsText = modsText ~~ " this"
withEnclosingDef(constr) { addVparamssText(tparamsTxt ~~ modsText, vparamss) }
Expand Down Expand Up @@ -670,7 +670,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}

protected def templateText(tree: TypeDef, impl: Template): Text = {
val decl = modText(tree.mods, keywordStr(if ((tree).mods is Trait) "trait" else "class"))
val decl = modText(tree.mods, tree.symbol, keywordStr(if ((tree).mods is Trait) "trait" else "class"))
decl ~~ typeText(nameIdText(tree)) ~ withEnclosingDef(tree) { toTextTemplate(impl) } ~
(if (tree.hasType && ctx.settings.verbose.value) i"[decls = ${tree.symbol.info.decls}]" else "")
}
Expand All @@ -693,16 +693,18 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {

protected def annotText(tree: untpd.Tree): Text = "@" ~ constrText(tree) // DD

protected def modText(mods: untpd.Modifiers, kw: String): Text = { // DD
protected def modText(mods: untpd.Modifiers, sym: Symbol, kw: String, suppress: FlagSet = EmptyFlags): Text = { // DD
val suppressKw = if (enclDefIsClass) mods is ParamAndLocal else mods is Param
var flagMask =
if (ctx.settings.YdebugFlags.value) AnyFlags
else if (suppressKw) PrintableFlags &~ Private
else PrintableFlags
else if (suppressKw) PrintableFlags &~ Private &~ suppress
else PrintableFlags &~ suppress
if (homogenizedView && mods.flags.isTypeFlags) flagMask &~= Implicit // drop implicit from classes
val flags = mods.flags & flagMask
val flagsText = if (flags.isEmpty) "" else keywordStr((mods.flags & flagMask).toString)
val annotations = filterModTextAnnots(mods.annotations)
val flags = (if (sym.exists) sym.flags else (mods.flags)) & flagMask
val flagsText = if (flags.isEmpty) "" else keywordStr(flags.toString)
val annotations = filterModTextAnnots(
if (sym.exists) sym.annotations.filterNot(_.isInstanceOf[Annotations.BodyAnnotation]).map(_.tree)
else mods.annotations)
Text(annotations.map(annotText), " ") ~~ flagsText ~~ (Str(kw) provided !suppressKw)
}

Expand Down
14 changes: 14 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/Inliner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import ErrorReporting.errorTree
import collection.mutable
import transform.TypeUtils._
import reporting.trace
import util.Positions.Position

object Inliner {
import tpd._
Expand Down Expand Up @@ -53,6 +54,7 @@ object Inliner {
* by excluding all symbols properly contained in the inlined method.
*/
def needsAccessor(sym: Symbol)(implicit ctx: Context) =
sym.isTerm &&
(sym.is(AccessFlags) || sym.privateWithin.exists) &&
!sym.owner.isContainedIn(inlineMethod)

Expand Down Expand Up @@ -537,6 +539,18 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {

var retainedInlineables = Set[Symbol]()

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) =>
tpe.info match {
case TypeAlias(alias) => return ensureAccessible(alias, superAccess, pos)
case _ =>
}
case _ =>
}
super.ensureAccessible(tpe, superAccess, pos)
}

override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context) =
tree.asInstanceOf[tpd.Tree] match {
case InlineableArg(rhs) => inlining.println(i"inline arg $tree -> $rhs"); rhs
Expand Down
22 changes: 22 additions & 0 deletions tests/pos/inlineAccesses.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
trait T {
object O
}

class C {
private type T = C
private var x = 0

inline def f = {
x += 1
x = x + 1
x
}
inline def dup = new T
}

object Test {

val c = new C
c.f
c.dup
}
Loading