@@ -8,12 +8,16 @@ import StdNames.nme
88import ast .untpd
99import ast .tpd ._
1010import config .Config
11+ import Decorators .*
1112
1213object ContextFunctionResults :
1314
1415 /** Annotate methods that have context function result types directly matched by context
1516 * closures on their right-hand side. Parameters to such closures will be integrated
1617 * as additional method parameters in erasure.
18+ *
19+ * A @ContextResultCount(n) annotation means that the method's result type
20+ * consists of a string of `n` nested context closures.
1721 */
1822 def annotateContextResults (mdef : DefDef )(using Context ): Unit =
1923 def contextResultCount (rhs : Tree , tp : Type ): Int = tp match
@@ -50,6 +54,15 @@ object ContextFunctionResults:
5054 crCount
5155 case none => 0
5256
57+ /** True iff `ContextResultCount` is not zero and all context functions in the result
58+ * type are erased.
59+ */
60+ def contextResultsAreErased (sym : Symbol )(using Context ): Boolean =
61+ def allErased (tp : Type ): Boolean = tp.dealias match
62+ case defn.ContextFunctionType (_, resTpe, isErased) => isErased && allErased(resTpe)
63+ case _ => true
64+ contextResultCount(sym) > 0 && allErased(sym.info.finalResultType)
65+
5366 /** Turn the first `crCount` context function types in the result type of `tp`
5467 * into the curried method types.
5568 */
@@ -86,33 +99,13 @@ object ContextFunctionResults:
8699 normalParamCount(sym.info)
87100 end totalParamCount
88101
89- /** The rightmost context function type in the result type of `meth`
90- * that represents `paramCount` curried, non-erased parameters that
91- * are included in the `contextResultCount` of `meth`.
92- * Example:
93- *
94- * Say we have `def m(x: A): B ?=> (C1, C2, C3) ?=> D ?=> E ?=> F`,
95- * paramCount == 4, and the contextResultCount of `m` is 3.
96- * Then we return the type `(C1, C2, C3) ?=> D ?=> E ?=> F`, since this
97- * type covers the 4 rightmost parameters C1, C2, C3 and D before the
98- * contextResultCount runs out at E ?=> F.
99- * Erased parameters are ignored; they contribute nothing to the
100- * parameter count.
101- */
102- def contextFunctionResultTypeCovering (meth : Symbol , paramCount : Int )(using Context ) =
103- atPhase(erasurePhase) {
104- // Recursive instances return pairs of context types and the
105- // # of parameters they represent.
106- def missingCR (tp : Type , crCount : Int ): (Type , Int ) =
107- if crCount == 0 then (tp, 0 )
108- else
109- val defn .ContextFunctionType (formals, resTpe, isErased) = tp : @ unchecked
110- val result @ (rt, nparams) = missingCR(resTpe, crCount - 1 )
111- assert(nparams <= paramCount)
112- if nparams == paramCount || isErased then result
113- else (tp, nparams + formals.length)
114- missingCR(meth.info.finalResultType, contextResultCount(meth))._1
115- }
102+ /** The `depth` levels nested context function type in the result type of `meth` */
103+ def contextFunctionResultTypeAfter (meth : Symbol , depth : Int )(using Context ) =
104+ def recur (tp : Type , n : Int ): Type =
105+ if n == 0 then tp
106+ else tp match
107+ case defn.ContextFunctionType (_, resTpe, _) => recur(resTpe, n - 1 )
108+ recur(meth.info.finalResultType, depth)
116109
117110 /** Should selection `tree` be eliminated since it refers to an `apply`
118111 * node of a context function type whose parameters will end up being
0 commit comments