@@ -600,39 +600,47 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
600
600
}
601
601
602
602
/** Expands a term macro used in apply role as `M(2)(3)` in `val x = M(2)(3)`.
603
+ * @param outerPt Expected type that comes from enclosing context (something that's traditionally called `pt`).
604
+ * @param innerPt Expected type that comes from the signature of a macro def, possibly wildcarded to help type inference.
603
605
* @see MacroExpander
604
606
*/
605
- def macroExpandApply (typer : Typer , expandee : Tree , mode : Mode , pt : Type ): Tree = {
606
- object expander extends TermMacroExpander (APPLY_ROLE , typer, expandee, mode, pt) {
607
- override def onSuccess (expanded0 : Tree ) = {
608
- def approximate (tp : Type ) = {
607
+ def macroExpandApply (typer : Typer , expandee : Tree , mode : Mode , outerPt : Type ): Tree = {
608
+ object expander extends TermMacroExpander (APPLY_ROLE , typer, expandee, mode, outerPt) {
609
+ lazy val innerPt = {
610
+ val tp = if (isNullaryInvocation(expandee)) expandee.tpe.finalResultType else expandee.tpe
611
+ if (isBlackbox(expandee)) tp
612
+ else {
609
613
// approximation is necessary for whitebox macros to guide type inference
610
614
// read more in the comments for onDelayed below
611
- if (isBlackbox(expandee)) tp
615
+ val undetparams = tp collect { case tp if tp.typeSymbol.isTypeParameter => tp.typeSymbol }
616
+ deriveTypeWithWildcards(undetparams)(tp)
617
+ }
618
+ }
619
+ override def onSuccess (expanded0 : Tree ) = {
620
+ // prematurely annotate the tree with a macro expansion attachment
621
+ // so that adapt called indirectly by typer.typed knows that it needs to apply the existential fixup
622
+ linkExpandeeAndExpanded(expandee, expanded0)
623
+
624
+ def typecheck (label : String , tree : Tree , pt : Type ): Tree = {
625
+ if (tree.isErrorTyped) tree
612
626
else {
613
- val undetparams = tp collect { case tp if tp.typeSymbol.isTypeParameter => tp.typeSymbol }
614
- deriveTypeWithWildcards(undetparams)(tp)
627
+ if (macroDebugVerbose) println(s " $label (against pt = $pt): $tree" )
628
+ // `macroExpandApply` is called from `adapt`, where implicit conversions are disabled
629
+ // therefore we need to re-enable the conversions back temporarily
630
+ val result = typer.context.withImplicitsEnabled(typer.typed(tree, mode, pt))
631
+ if (result.isErrorTyped && macroDebugVerbose) println(s " $label has failed: ${typer.context.reportBuffer.errors}" )
632
+ result
615
633
}
616
634
}
617
- val macroPt = approximate(if (isNullaryInvocation(expandee)) expandee.tpe.finalResultType else expandee.tpe)
618
- val expanded = if (isBlackbox(expandee)) atPos(enclosingMacroPosition.focus)(Typed (expanded0, TypeTree (macroPt))) else expanded0
619
635
620
- // prematurely annotate the tree with a macro expansion attachment
621
- // so that adapt called indirectly by typer.typed knows that it needs to apply the existential fixup
622
- linkExpandeeAndExpanded(expandee, expanded)
623
-
624
- // `macroExpandApply` is called from `adapt`, where implicit conversions are disabled
625
- // therefore we need to re-enable the conversions back temporarily
626
- if (macroDebugVerbose) println(s " typecheck #1 (against macroPt = $macroPt): $expanded" )
627
- val expanded1 = typer.context.withImplicitsEnabled(typer.typed(expanded, mode, macroPt))
628
- if (expanded1.isErrorTyped) {
629
- if (macroDebugVerbose) println(s " typecheck #1 has failed: ${typer.context.reportBuffer.errors}" )
630
- expanded1
636
+ if (isBlackbox(expandee)) {
637
+ val expanded1 = atPos(enclosingMacroPosition.focus)(Typed (expanded0, TypeTree (innerPt)))
638
+ val expanded2 = typecheck(" blackbox typecheck #1" , expanded1, innerPt)
639
+ typecheck(" blackbox typecheck #2" , expanded1, outerPt)
631
640
} else {
632
- if (macroDebugVerbose) println(s " typecheck #2 (against pt = $pt): $expanded1" )
633
- val expanded2 = typer.context.withImplicitsEnabled(super .onSuccess(expanded1))
634
- if (macroDebugVerbose && expanded2.isErrorTyped) println(s " typecheck #2 has failed: ${typer.context.reportBuffer.errors}" )
635
- expanded2
641
+ val expanded1 = expanded0
642
+ val expanded2 = typecheck(" whitebox typecheck #1" , expanded1, innerPt)
643
+ typecheck(" whitebox typecheck #2" , expanded2, outerPt)
636
644
}
637
645
}
638
646
override def onDelayed (delayed : Tree ) = {
@@ -686,11 +694,11 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
686
694
// Thanks to that the materializer can take a look at what's going on and react accordingly.
687
695
val shouldInstantiate = typer.context.undetparams.nonEmpty && ! mode.inPolyMode
688
696
if (shouldInstantiate) {
689
- if (isBlackbox(expandee)) typer.instantiatePossiblyExpectingUnit(delayed, mode, pt )
697
+ if (isBlackbox(expandee)) typer.instantiatePossiblyExpectingUnit(delayed, mode, outerPt )
690
698
else {
691
699
forced += delayed
692
- typer.infer.inferExprInstance(delayed, typer.context.extractUndetparams(), pt , keepNothings = false )
693
- macroExpandApply(typer, delayed, mode, pt )
700
+ typer.infer.inferExprInstance(delayed, typer.context.extractUndetparams(), outerPt , keepNothings = false )
701
+ macroExpandApply(typer, delayed, mode, outerPt )
694
702
}
695
703
} else delayed
696
704
}
0 commit comments