Skip to content

Commit fb65487

Browse files
Create InlineTreeMap, make helper function for param accessors
1 parent 11727af commit fb65487

File tree

2 files changed

+52
-44
lines changed

2 files changed

+52
-44
lines changed

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

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,53 @@ class Inliner(val call: tpd.Tree)(using Context):
517517
}
518518
}
519519

520+
protected class InlinerTreeMap extends (Tree => Tree) {
521+
def apply(tree: Tree) = tree match {
522+
case tree: This =>
523+
tree.tpe match {
524+
case thistpe: ThisType =>
525+
val cls = thistpe.cls
526+
if cls.isInlineTrait then
527+
integrate(This(ctx.owner.asClass).withSpan(call.span), cls)
528+
else thisProxy.get(cls) match {
529+
case Some(t) =>
530+
val thisRef = ref(t).withSpan(call.span)
531+
inlinedFromOutside(thisRef)(tree.span)
532+
case None => tree
533+
}
534+
case _ => tree
535+
}
536+
case tree: Ident =>
537+
/* Span of the argument. Used when the argument is inlined directly without a binding */
538+
def argSpan =
539+
if (tree.name == nme.WILDCARD) tree.span // From type match
540+
else if (tree.symbol.isTypeParam && tree.symbol.owner.isClass) tree.span // TODO is this the correct span?
541+
else paramSpan(tree.name)
542+
val inlinedCtx = ctx.withSource(inlinedMethod.topLevelClass.source)
543+
paramProxy.get(tree.tpe) match {
544+
case Some(t) if tree.isTerm && t.isSingleton =>
545+
val inlinedSingleton = singleton(t).withSpan(argSpan)
546+
inlinedFromOutside(inlinedSingleton)(tree.span)
547+
case Some(t) if tree.isType =>
548+
inlinedFromOutside(TypeTree(t).withSpan(argSpan))(tree.span)
549+
case _ => tree
550+
}
551+
case tree @ Select(qual: This, name) if tree.symbol.is(Private) && tree.symbol.isInlineMethod =>
552+
// This inline method refers to another (private) inline method (see tests/pos/i14042.scala).
553+
// We insert upcast to access the private inline method once inlined. This makes the selection
554+
// keep the symbol when re-typechecking in the InlineTyper. The method is inlined and hence no
555+
// reference to a private method is kept at runtime.
556+
cpy.Select(tree)(qual.asInstance(qual.tpe.widen), name)
557+
558+
case tree => tree
559+
}
560+
561+
private def inlinedFromOutside(tree: Tree)(span: Span): Tree =
562+
Inlined(EmptyTree, Nil, tree)(using ctx.withSource(inlinedMethod.topLevelClass.source)).withSpan(span)
563+
}
564+
520565
protected val inlinerTypeMap: InlinerTypeMap = InlinerTypeMap()
566+
protected val inlinerTreeMap: InlinerTreeMap = InlinerTreeMap()
521567

522568
/** The Inlined node representing the inlined call */
523569
def inlined(rhsToInline: tpd.Tree): (List[MemberDef], Tree) =
@@ -564,54 +610,13 @@ class Inliner(val call: tpd.Tree)(using Context):
564610

565611
val inlineCtx = inlineContext(call).fresh.setTyper(inlineTyper).setNewScope
566612

567-
def inlinedFromOutside(tree: Tree)(span: Span): Tree =
568-
Inlined(EmptyTree, Nil, tree)(using ctx.withSource(inlinedMethod.topLevelClass.source)).withSpan(span)
569-
570613
// A tree type map to prepare the inlined body for typechecked.
571614
// The translation maps references to `this` and parameters to
572615
// corresponding arguments or proxies on the type and term level. It also changes
573616
// the owner from the inlined method to the current owner.
574617
val inliner = new InlinerMap(
575618
typeMap = inlinerTypeMap,
576-
treeMap = {
577-
case tree: This =>
578-
tree.tpe match {
579-
case thistpe: ThisType =>
580-
val cls = thistpe.cls
581-
if cls.isInlineTrait then
582-
integrate(This(ctx.owner.asClass).withSpan(call.span), cls)
583-
else thisProxy.get(cls) match {
584-
case Some(t) =>
585-
val thisRef = ref(t).withSpan(call.span)
586-
inlinedFromOutside(thisRef)(tree.span)
587-
case None => tree
588-
}
589-
case _ => tree
590-
}
591-
case tree: Ident =>
592-
/* Span of the argument. Used when the argument is inlined directly without a binding */
593-
def argSpan =
594-
if (tree.name == nme.WILDCARD) tree.span // From type match
595-
else if (tree.symbol.isTypeParam && tree.symbol.owner.isClass) tree.span // TODO is this the correct span?
596-
else paramSpan(tree.name)
597-
val inlinedCtx = ctx.withSource(inlinedMethod.topLevelClass.source)
598-
paramProxy.get(tree.tpe) match {
599-
case Some(t) if tree.isTerm && t.isSingleton =>
600-
val inlinedSingleton = singleton(t).withSpan(argSpan)
601-
inlinedFromOutside(inlinedSingleton)(tree.span)
602-
case Some(t) if tree.isType =>
603-
inlinedFromOutside(TypeTree(t).withSpan(argSpan))(tree.span)
604-
case _ => tree
605-
}
606-
case tree @ Select(qual: This, name) if tree.symbol.is(Private) && tree.symbol.isInlineMethod =>
607-
// This inline method refers to another (private) inline method (see tests/pos/i14042.scala).
608-
// We insert upcast to access the private inline method once inlined. This makes the selection
609-
// keep the symbol when re-typechecking in the InlineTyper. The method is inlined and hence no
610-
// reference to a private method is kept at runtime.
611-
cpy.Select(tree)(qual.asInstance(qual.tpe.widen), name)
612-
613-
case tree => tree
614-
},
619+
treeMap = inlinerTreeMap,
615620
oldOwners = inlinedMethod :: Nil,
616621
newOwners = ctx.owner :: Nil,
617622
substFrom = Nil,

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,9 @@ object Inlines:
505505
private def isStatAlreadyOverridden(stat: Tree): Boolean =
506506
overriddenDecls.contains(stat.symbol)
507507

508+
extension (sym: Symbol)
509+
private def isTermParamAccessor: Boolean = !sym.isType && sym.is(ParamAccessor)
510+
508511
private def expandStat(stat: tpd.Tree, inlinedSym: Symbol): tpd.Tree = stat match
509512
case stat: ValDef =>
510513
inlinedValDef(stat, inlinedSym)
@@ -523,7 +526,7 @@ object Inlines:
523526
case _ =>
524527
var flags = sym.flags | Synthetic
525528
if sym.isType || !sym.is(Private) then flags |= Override
526-
if !sym.isType && sym.is(ParamAccessor) then flags &~= ParamAccessor
529+
if sym.isTermParamAccessor then flags &~= ParamAccessor
527530
sym.copy(
528531
owner = ctx.owner,
529532
flags = flags,
@@ -539,7 +542,7 @@ object Inlines:
539542

540543
private def inlinedValDef(vdef: ValDef, inlinedSym: Symbol)(using Context): ValDef =
541544
val rhs =
542-
if vdef.symbol.is(ParamAccessor) then
545+
if vdef.symbol.isTermParamAccessor then
543546
paramAccessorsValueOf(vdef.symbol.name)
544547
else
545548
inlinedRhs(vdef.rhs.changeOwner(vdef.symbol, inlinedSym))

0 commit comments

Comments
 (0)