@@ -867,11 +867,13 @@ class CheckCaptures extends Recheck, SymTransformer:
867
867
if eparent1 eq eparent then expected
868
868
else CapturingType (eparent1, refs, boxed = expected0.isBoxed)
869
869
case expected @ defn.FunctionOf (args, resultType, isContextual)
870
- if defn.isNonRefinedFunction(expected) && defn.isFunctionNType(actual) && ! defn.isNonRefinedFunction(actual) =>
871
- val expected1 = depFun(args, resultType, isContextual)
872
- expected1
873
- case _ =>
874
- expected
870
+ if defn.isNonRefinedFunction(expected) =>
871
+ actual match
872
+ case RefinedType (parent, nme.apply, rinfo : MethodType )
873
+ if defn.isFunctionNType(actual) =>
874
+ depFun(args, resultType, isContextual, rinfo.paramNames)
875
+ case _ => expected
876
+ case _ => expected
875
877
recur(expected)
876
878
877
879
/** For the expected type, implement the rule outlined in #14390:
@@ -1239,7 +1241,7 @@ class CheckCaptures extends Recheck, SymTransformer:
1239
1241
* compensate this by pushing the widened capture set of `f` into ?1.
1240
1242
* This solves the soundness issue caused by the ill-formness of ?1.
1241
1243
*/
1242
- private def healTypeParam (tree : Tree )(using Context ): Unit =
1244
+ private def healTypeParam (tree : Tree , paramName : TypeName , meth : Symbol )(using Context ): Unit =
1243
1245
val checker = new TypeTraverser :
1244
1246
private var allowed : SimpleIdentitySet [TermParamRef ] = SimpleIdentitySet .empty
1245
1247
@@ -1261,8 +1263,14 @@ class CheckCaptures extends Recheck, SymTransformer:
1261
1263
val widened = ref.captureSetOfInfo
1262
1264
val added = widened.filter(isAllowed(_))
1263
1265
capt.println(i " heal $ref in $cs by widening to $added" )
1264
- checkSubset(added, cs, tree.srcPos)
1265
- widened.elems.foreach(recur)
1266
+ if ! added.subCaptures(cs, frozen = false ).isOK then
1267
+ val location = if meth.exists then i " of $meth" else " "
1268
+ val debugSetInfo = if ctx.settings.YccDebug .value then i " $cs" else " "
1269
+ report.error(
1270
+ i " local reference ${ref.paramName} leaks into outer capture set $debugSetInfo of type parameter $paramName$location" ,
1271
+ tree.srcPos)
1272
+ else
1273
+ widened.elems.foreach(recur)
1266
1274
case _ =>
1267
1275
recur(elem)
1268
1276
@@ -1303,14 +1311,12 @@ class CheckCaptures extends Recheck, SymTransformer:
1303
1311
case t @ TypeApply (fun, args) =>
1304
1312
fun.knownType.widen match
1305
1313
case tl : PolyType =>
1306
- val normArgs = args.lazyZip(tl.paramInfos).map { (arg, bounds) =>
1314
+ val normArgs = args.lazyZip(tl.paramInfos).map: (arg, bounds) =>
1307
1315
arg.withType(arg.knownType.forceBoxStatus(
1308
1316
bounds.hi.isBoxedCapturing | bounds.lo.isBoxedCapturing))
1309
- }
1310
1317
checkBounds(normArgs, tl)
1318
+ args.lazyZip(tl.paramNames).foreach(healTypeParam(_, _, fun.symbol))
1311
1319
case _ =>
1312
-
1313
- args.foreach(healTypeParam(_))
1314
1320
case _ =>
1315
1321
end check
1316
1322
end checker
0 commit comments