Skip to content

Commit e6a07e2

Browse files
committed
Pretype nested transparent applications
1 parent 802b157 commit e6a07e2

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
495495
case _ => tree
496496
}}
497497

498-
val inlineTyper = if (meth.isTransparentMethod) new InlineTyper else new InlineReTyper
498+
val inlineTyper = if (meth.isTransparentMethod) new TransparentTyper else new InlineReTyper
499499
val inlineCtx = inlineContext(call).fresh.setTyper(inlineTyper).setNewScope
500500

501501
// The complete translation maps references to `this` and parameters to
@@ -523,16 +523,18 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
523523
expansion
524524
}
525525

526-
trace(i"inlining $call\n, BINDINGS =\n${bindingsBuf.toList}%\n%\nEXPANSION =\n$expansion", inlining, show = true) {
526+
trace(i"inlining $call", inlining, show = true) {
527527

528528
// The final expansion runs a typing pass over the inlined tree. See InlineTyper for details.
529529
val expansion1 = inlineTyper.typed(expansion, pt)(inlineCtx)
530530

531531
/** All bindings in `bindingsBuf` except bindings of inlineable closures */
532532
val bindings = bindingsBuf.toList.map(_.withPos(call.pos))
533533

534-
inlining.println(i"original bindings = $bindings%\n%")
535-
inlining.println(i"original expansion = $expansion1")
534+
if (ctx.settings.verbose.value) {
535+
inlining.println(i"original bindings = $bindings%\n%")
536+
inlining.println(i"original expansion = $expansion1")
537+
}
536538

537539
val (finalBindings, finalExpansion) = dropUnusedDefs(bindings, expansion1)
538540

@@ -625,13 +627,24 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
625627
}
626628

627629
/** A full typer used for transparent methods */
628-
private class InlineTyper extends Typer with InlineTyping {
630+
private class TransparentTyper extends Typer with InlineTyping {
629631

630632
override def typedTypedSplice(tree: untpd.TypedSplice)(implicit ctx: Context): Tree =
631633
tree.splice match {
632634
case InlineableArg(rhs) => inlining.println(i"inline arg $tree -> $rhs"); rhs
633635
case _ => super.typedTypedSplice(tree)
634636
}
637+
638+
/** Pre-type any nested calls to transparent methods. Otherwise the declared result type
639+
* of these methods can influence constraints
640+
*/
641+
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context) = {
642+
def typeTransparent(tree: untpd.Tree): untpd.Tree =
643+
if (tree.symbol.isTransparentMethod) untpd.TypedSplice(typed(tree))
644+
else tree
645+
val tree1 = tree.args.mapConserve(typeTransparent)
646+
super.typedApply(untpd.cpy.Apply(tree)(tree.fun, tree1), pt)
647+
}
635648
}
636649

637650
/** A re-typer used for inlined methods */

0 commit comments

Comments
 (0)