@@ -1129,7 +1129,7 @@ class Typer extends Namer
1129
1129
case _ =>
1130
1130
}
1131
1131
1132
- val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length)
1132
+ val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length, tree )
1133
1133
1134
1134
/** The inferred parameter type for a parameter in a lambda that does
1135
1135
* not have an explicit type given.
@@ -1445,17 +1445,40 @@ class Typer extends Namer
1445
1445
}
1446
1446
1447
1447
def typedReturn (tree : untpd.Return )(using Context ): Return = {
1448
+
1449
+ /** If `pt` is a context function type, its return type. If the CFT
1450
+ * is dependent, instantiate with the parameters of the associated
1451
+ * anonymous function.
1452
+ * @param paramss the parameters of the anonymous functions
1453
+ * enclosing the return expression
1454
+ */
1455
+ def instantiateCFT (pt : Type , paramss : List [List [Symbol ]]): Type =
1456
+ val ift = defn.asContextFunctionType(pt)
1457
+ if ift.exists then
1458
+ ift.nonPrivateMember(nme.apply).info match
1459
+ case appType : MethodType =>
1460
+ instantiateCFT(appType.instantiate(paramss.head.map(_.termRef)), paramss.tail)
1461
+ else pt
1462
+
1448
1463
def returnProto (owner : Symbol , locals : Scope ): Type =
1449
1464
if (owner.isConstructor) defn.UnitType
1450
- else owner.info match {
1451
- case info : PolyType =>
1452
- val tparams = locals.toList.takeWhile(_ is TypeParam )
1453
- assert(info.paramNames.length == tparams.length,
1454
- i " return mismatch from $owner, tparams = $tparams, locals = ${locals.toList}%, % " )
1455
- info.instantiate(tparams.map(_.typeRef)).finalResultType
1456
- case info =>
1457
- info.finalResultType
1458
- }
1465
+ else
1466
+ val rt = owner.info match
1467
+ case info : PolyType =>
1468
+ val tparams = locals.toList.takeWhile(_ is TypeParam )
1469
+ assert(info.paramNames.length == tparams.length,
1470
+ i " return mismatch from $owner, tparams = $tparams, locals = ${locals.toList}%, % " )
1471
+ info.instantiate(tparams.map(_.typeRef)).finalResultType
1472
+ case info =>
1473
+ info.finalResultType
1474
+ def iftParamss = ctx.owner.ownersIterator
1475
+ .filter(_.is(Method , butNot = Accessor ))
1476
+ .takeWhile(_.isAnonymousFunction)
1477
+ .toList
1478
+ .reverse
1479
+ .map(_.paramSymss.head)
1480
+ instantiateCFT(rt, iftParamss)
1481
+
1459
1482
def enclMethInfo (cx : Context ): (Tree , Type ) = {
1460
1483
val owner = cx.owner
1461
1484
if (owner.isType) {
@@ -3147,7 +3170,7 @@ class Typer extends Namer
3147
3170
3148
3171
def isContextFunctionRef (wtp : Type ): Boolean = wtp match {
3149
3172
case RefinedType (parent, nme.apply, _) =>
3150
- isContextFunctionRef(parent) // apply refinements indicate a dependent IFT
3173
+ isContextFunctionRef(parent) // apply refinements indicate a dependent CFT
3151
3174
case _ =>
3152
3175
val underlying = wtp.underlyingClassRef(refinementOK = false ) // other refinements are not OK
3153
3176
defn.isContextFunctionClass(underlying.classSymbol)
0 commit comments