Skip to content

Commit 01ee90c

Browse files
committed
Pretype nested transparent applications
1 parent 309da1d commit 01ee90c

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
@@ -613,7 +613,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
613613
case _ => tree
614614
}}
615615

616-
val inlineTyper = if (meth.isTransparentMethod) new InlineTyper else new InlineReTyper
616+
val inlineTyper = if (meth.isTransparentMethod) new TransparentTyper else new InlineReTyper
617617
val inlineCtx = inlineContext(call).fresh.setTyper(inlineTyper).setNewScope
618618

619619
// The complete translation maps references to `this` and parameters to
@@ -641,16 +641,18 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
641641
expansion
642642
}
643643

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

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

649649
/** All bindings in `bindingsBuf` except bindings of inlineable closures */
650650
val bindings = bindingsBuf.toList.map(_.withPos(call.pos))
651651

652-
inlining.println(i"original bindings = $bindings%\n%")
653-
inlining.println(i"original expansion = $expansion1")
652+
if (ctx.settings.verbose.value) {
653+
inlining.println(i"original bindings = $bindings%\n%")
654+
inlining.println(i"original expansion = $expansion1")
655+
}
654656

655657
val (finalBindings, finalExpansion) = dropUnusedDefs(bindings, expansion1)
656658

@@ -754,13 +756,24 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
754756
}
755757

756758
/** A full typer used for transparent methods */
757-
private class InlineTyper extends Typer with InlineTyping {
759+
private class TransparentTyper extends Typer with InlineTyping {
758760

759761
override def typedTypedSplice(tree: untpd.TypedSplice)(implicit ctx: Context): Tree =
760762
tree.splice match {
761763
case InlineableArg(rhs) => inlining.println(i"inline arg $tree -> $rhs"); rhs
762764
case _ => super.typedTypedSplice(tree)
763765
}
766+
767+
/** Pre-type any nested calls to transparent methods. Otherwise the declared result type
768+
* of these methods can influence constraints
769+
*/
770+
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context) = {
771+
def typeTransparent(tree: untpd.Tree): untpd.Tree =
772+
if (tree.symbol.isTransparentMethod) untpd.TypedSplice(typed(tree))
773+
else tree
774+
val tree1 = tree.args.mapConserve(typeTransparent)
775+
super.typedApply(untpd.cpy.Apply(tree)(tree.fun, tree1), pt)
776+
}
764777
}
765778

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

0 commit comments

Comments
 (0)