@@ -517,7 +517,53 @@ class Inliner(val call: tpd.Tree)(using Context):
517
517
}
518
518
}
519
519
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
+
520
565
protected val inlinerTypeMap : InlinerTypeMap = InlinerTypeMap ()
566
+ protected val inlinerTreeMap : InlinerTreeMap = InlinerTreeMap ()
521
567
522
568
/** The Inlined node representing the inlined call */
523
569
def inlined (rhsToInline : tpd.Tree ): (List [MemberDef ], Tree ) =
@@ -564,54 +610,13 @@ class Inliner(val call: tpd.Tree)(using Context):
564
610
565
611
val inlineCtx = inlineContext(call).fresh.setTyper(inlineTyper).setNewScope
566
612
567
- def inlinedFromOutside (tree : Tree )(span : Span ): Tree =
568
- Inlined (EmptyTree , Nil , tree)(using ctx.withSource(inlinedMethod.topLevelClass.source)).withSpan(span)
569
-
570
613
// A tree type map to prepare the inlined body for typechecked.
571
614
// The translation maps references to `this` and parameters to
572
615
// corresponding arguments or proxies on the type and term level. It also changes
573
616
// the owner from the inlined method to the current owner.
574
617
val inliner = new InlinerMap (
575
618
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,
615
620
oldOwners = inlinedMethod :: Nil ,
616
621
newOwners = ctx.owner :: Nil ,
617
622
substFrom = Nil ,
0 commit comments