@@ -1129,7 +1129,7 @@ class Typer extends Namer
11291129 case _ =>
11301130 }
11311131
1132- val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length)
1132+ val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length, tree )
11331133
11341134 /** The inferred parameter type for a parameter in a lambda that does
11351135 * not have an explicit type given.
@@ -1445,17 +1445,40 @@ class Typer extends Namer
14451445 }
14461446
14471447 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+
14481463 def returnProto (owner : Symbol , locals : Scope ): Type =
14491464 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+
14591482 def enclMethInfo (cx : Context ): (Tree , Type ) = {
14601483 val owner = cx.owner
14611484 if (owner.isType) {
@@ -3147,7 +3170,7 @@ class Typer extends Namer
31473170
31483171 def isContextFunctionRef (wtp : Type ): Boolean = wtp match {
31493172 case RefinedType (parent, nme.apply, _) =>
3150- isContextFunctionRef(parent) // apply refinements indicate a dependent IFT
3173+ isContextFunctionRef(parent) // apply refinements indicate a dependent CFT
31513174 case _ =>
31523175 val underlying = wtp.underlyingClassRef(refinementOK = false ) // other refinements are not OK
31533176 defn.isContextFunctionClass(underlying.classSymbol)
0 commit comments