Skip to content

Commit 47f5940

Browse files
committed
Prepare to have both inlined and transparent methods
All necessary changes except for those in the Inliner itself.
1 parent 14bbce6 commit 47f5940

File tree

8 files changed

+52
-23
lines changed

8 files changed

+52
-23
lines changed

compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ class TreeTypeMap(
9595
val (tmap2, vparamss1) = tmap1.transformVParamss(vparamss)
9696
val res = cpy.DefDef(ddef)(name, tparams1, vparamss1, tmap2.transform(tpt), tmap2.transform(ddef.rhs))
9797
res.symbol.transformAnnotations {
98-
case ann: BodyAnnotation => ann.derivedAnnotation(res.rhs)
98+
case ann: BodyAnnotation =>
99+
if (res.symbol.isTransparentMethod) ann.derivedAnnotation(transform(ann.tree))
100+
else ann.derivedAnnotation(res.rhs)
99101
case ann => ann
100102
}
101103
res
@@ -126,7 +128,7 @@ class TreeTypeMap(
126128
override def transformStats(trees: List[tpd.Tree])(implicit ctx: Context) =
127129
transformDefs(trees)._2
128130

129-
private def transformDefs[TT <: tpd.Tree](trees: List[TT])(implicit ctx: Context): (TreeTypeMap, List[TT]) = {
131+
def transformDefs[TT <: tpd.Tree](trees: List[TT])(implicit ctx: Context): (TreeTypeMap, List[TT]) = {
130132
val tmap = withMappedSyms(tpd.localSyms(trees))
131133
(tmap, tmap.transformSub(trees))
132134
}

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import scala.io.Codec
2020
/** Some creators for typed trees */
2121
object tpd extends Trees.Instance[Type] with TypedTreeInfo {
2222

23+
case class UntypedSplice(splice: untpd.Tree) extends Tree
24+
2325
private def ta(implicit ctx: Context) = ctx.typeAssigner
2426

2527
def Ident(tp: NamedType)(implicit ctx: Context): Ident =
@@ -471,8 +473,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
471473
} else foldOver(sym, tree)
472474
}
473475

474-
case class UntypedSplice(splice: untpd.Tree) extends Tree
475-
476476
override val cpy: TypedTreeCopier = // Type ascription needed to pick up any new members in TreeCopier (currently there are none)
477477
new TypedTreeCopier
478478

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,8 @@ class TreePickler(pickler: TastyPickler) {
637637
// a different toplevel class, it is impossible to pickle a reference to it.
638638
// Such annotations will be reconstituted when unpickling the child class.
639639
// See tests/pickling/i3149.scala
640-
case _ => ann.symbol == defn.BodyAnnot
641-
// inline bodies are reconstituted automatically when unpickling
640+
case _ => ann.symbol == defn.BodyAnnot && owner.isInlinedMethod
641+
// bodies of inlined (but not transparent) methods are reconstituted automatically when unpickling
642642
}
643643

644644
def pickleAnnotation(owner: Symbol, ann: Annotation)(implicit ctx: Context) =

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,9 @@ class TreeUnpickler(reader: TastyReader,
633633
val end = readEnd()
634634
val tp = readType()
635635
val lazyAnnotTree = readLaterWithOwner(end, rdr => ctx => rdr.readTerm()(ctx))
636-
637-
owner =>
636+
if (tp.isRef(defn.BodyAnnot))
637+
LazyBodyAnnotation(implicit ctx => lazyAnnotTree(owner).complete)
638+
else
638639
Annotation.deferredSymAndTree(
639640
implicit ctx => tp.typeSymbol,
640641
implicit ctx => lazyAnnotTree(owner).complete)

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,19 +1103,24 @@ trait Implicits { self: Typer =>
11031103
val eligible =
11041104
if (contextual) ctx.implicits.eligible(wildProto)
11051105
else implicitScope(wildProto).eligible
1106-
searchImplicits(eligible, contextual).recoverWith {
1107-
failure => failure.reason match {
1108-
case _: AmbiguousImplicits => failure
1109-
case reason =>
1110-
if (contextual)
1111-
bestImplicit(contextual = false).recoverWith {
1112-
failure2 => reason match {
1113-
case (_: DivergingImplicit) | (_: ShadowedImplicit) => failure
1114-
case _ => failure2
1106+
searchImplicits(eligible, contextual) match {
1107+
case result: SearchSuccess =>
1108+
if (contextual && ctx.mode.is(Mode.TransparentBody))
1109+
Inliner.markContextualImplicit(result.tree)
1110+
result
1111+
case failure: SearchFailure =>
1112+
failure.reason match {
1113+
case _: AmbiguousImplicits => failure
1114+
case reason =>
1115+
if (contextual)
1116+
bestImplicit(contextual = false).recoverWith {
1117+
failure2 => reason match {
1118+
case (_: DivergingImplicit) | (_: ShadowedImplicit) => failure
1119+
case _ => failure2
1120+
}
11151121
}
1116-
}
1117-
else failure
1118-
}
1122+
else failure
1123+
}
11191124
}
11201125
}
11211126

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,20 @@ import collection.mutable
2727
import transform.TypeUtils._
2828
import reporting.trace
2929
import util.Positions.Position
30+
import util.Property
3031

3132
object Inliner {
3233
import tpd._
3334

35+
/** Marks an implicit reference found in the context (as opposed to the implicit scope)
36+
* from an inlineable body. Such references will be carried along with the body to
37+
* the expansion site.
38+
*/
39+
private val ContextualImplicit = new Property.StickyKey[Unit]
40+
41+
def markContextualImplicit(tree: Tree)(implicit ctx: Context): Unit =
42+
methPart(tree).putAttachment(ContextualImplicit, ())
43+
3444
class InlineAccessors extends AccessProxies {
3545

3646
/** If an inline accessor name wraps a unique inline name, this is taken as indication
@@ -212,7 +222,7 @@ object Inliner {
212222
* to have the inlined method as owner.
213223
*/
214224
def registerInlineInfo(
215-
inlined: Symbol, treeExpr: Context => Tree)(implicit ctx: Context): Unit = {
225+
inlined: Symbol, originalBody: untpd.Tree, treeExpr: Context => Tree)(implicit ctx: Context): Unit = {
216226
inlined.unforcedAnnotation(defn.BodyAnnot) match {
217227
case Some(ann: ConcreteBodyAnnotation) =>
218228
case Some(ann: LazyBodyAnnotation) if ann.isEvaluated =>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ class Namer { typer: Typer =>
825825
case original: untpd.DefDef if sym.isInlineableMethod =>
826826
Inliner.registerInlineInfo(
827827
sym,
828+
original.rhs,
828829
implicit ctx => typedAheadExpr(original).asInstanceOf[tpd.DefDef].rhs
829830
)(localContext(sym))
830831
case _ =>

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,7 @@ class Typer extends Namer
14321432
val rhs1 = normalizeErasedRhs(typedExpr(ddef.rhs, tpt1.tpe)(rhsCtx), sym)
14331433

14341434
// Overwrite inline body to make sure it is not evaluated twice
1435-
if (sym.isInlineableMethod) Inliner.registerInlineInfo(sym, _ => rhs1)
1435+
if (sym.isInlineableMethod) Inliner.registerInlineInfo(sym, ddef.rhs, _ => rhs1)
14361436

14371437
if (sym.isConstructor && !sym.isPrimaryConstructor)
14381438
for (param <- tparams1 ::: vparamss1.flatten)
@@ -1904,7 +1904,17 @@ class Typer extends Namer
19041904
case none =>
19051905
typed(mdef) match {
19061906
case mdef1: DefDef if Inliner.hasBodyToInline(mdef1.symbol) =>
1907-
buf += inlineExpansion(mdef1)
1907+
if (mdef1.symbol.isInlinedMethod) {
1908+
buf += inlineExpansion(mdef1)
1909+
// replace body with expansion, because it will be used as inlined body
1910+
// from separately compiled files - the original BodyAnnotation is not kept.
1911+
}
1912+
else {
1913+
assert(mdef.symbol.isTransparentMethod)
1914+
Inliner.bodyToInline(mdef1.symbol) // just make sure accessors are computed,
1915+
buf += mdef1 // but keep original definition, since inline-expanded code
1916+
// is pickled in this case.
1917+
}
19081918
case mdef1 =>
19091919
import untpd.modsDeco
19101920
mdef match {

0 commit comments

Comments
 (0)