Skip to content

Commit 023283d

Browse files
committed
add box adaptation for poly functions
1 parent ae3f52e commit 023283d

File tree

1 file changed

+53
-9
lines changed

1 file changed

+53
-9
lines changed

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,11 @@ class CheckCaptures extends Recheck, SymTransformer:
605605
try
606606
val (eargs, eres) = expected.dealias match
607607
case defn.FunctionOf(eargs, eres, _, _) => (eargs, eres)
608-
case _ => (aargs.map(_ => WildcardType), WildcardType)
608+
case expected => expected.stripped match
609+
case expected: MethodType => (expected.paramInfos, expected.resType)
610+
case expected @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionType(expected) => (rinfo.paramInfos, rinfo.resType)
611+
case _ =>
612+
(aargs.map(_ => WildcardType), WildcardType)
609613
val aargs1 = aargs.zipWithConserve(eargs) { (aarg, earg) => adapt(aarg, earg, !covariant) }
610614
val ares1 = adapt(ares, eres, covariant)
611615

@@ -618,6 +622,31 @@ class CheckCaptures extends Recheck, SymTransformer:
618622
finally
619623
curEnv = saved
620624

625+
def adaptTypeFun(
626+
actualTp: (Type, CaptureSet), ares: Type, expected: Type,
627+
covariant: Boolean, boxed: Boolean,
628+
reconstruct: Type => Type): (Type, CaptureSet) =
629+
val (actual, cs0) = actualTp
630+
val saved = curEnv
631+
curEnv = Env(curEnv.owner, CaptureSet.Var(), isBoxed = false, if boxed then null else curEnv)
632+
633+
try
634+
val eres = expected.dealias.stripCapturing match
635+
case RefinedType(_, _, rinfo: PolyType) => rinfo.resType
636+
case _ => WildcardType
637+
638+
val ares1 = adapt(ares, eres, covariant)
639+
640+
val resTp =
641+
if ares1 eq ares then actual
642+
else reconstruct(ares1)
643+
644+
curEnv.captured.asVar.markSolved()
645+
(resTp, curEnv.captured ++ cs0)
646+
finally
647+
curEnv = saved
648+
end adaptTypeFun
649+
621650
def adaptInfo(actual: Type, expected: Type, covariant: Boolean): String =
622651
val arrow = if covariant then "~~>" else "<~~"
623652
i"adapting $actual $arrow $expected"
@@ -632,15 +661,19 @@ class CheckCaptures extends Recheck, SymTransformer:
632661
case actual =>
633662
((actual, CaptureSet(), false), reconstruct)
634663

635-
val (actualTp, recon) = destructCapturingType(actual, x => x)
636-
val (parent1, cs1, isBoxed1) = adaptCapturingType(actualTp, expected, covariant)
637-
638-
recon(CapturingType(parent1, cs1, isBoxed1))
664+
if expected.isInstanceOf[WildcardType] then
665+
actual
666+
else
667+
val (actualTp, recon) = destructCapturingType(actual, x => x)
668+
val (parent1, cs1, isBoxed1) = adaptCapturingType(actualTp, expected, covariant)
669+
recon(CapturingType(parent1, cs1, isBoxed1))
639670
}
640671

641-
def adaptCapturingType(actual: (Type, CaptureSet, Boolean),
642-
expected: Type,
643-
covariant: Boolean): (Type, CaptureSet, Boolean) =
672+
def adaptCapturingType(
673+
actual: (Type, CaptureSet, Boolean),
674+
expected: Type,
675+
covariant: Boolean
676+
): (Type, CaptureSet, Boolean) =
644677
val (parent, cs, actualIsBoxed) = actual
645678

646679
val needsAdaptation = actualIsBoxed != expected.isBoxedCapturing
@@ -656,6 +689,17 @@ class CheckCaptures extends Recheck, SymTransformer:
656689
(aargs1, ares1) =>
657690
rinfo.derivedLambdaType(paramInfos = aargs1, resType = ares1)
658691
.toFunctionType(isJava = false, alwaysDependent = true))
692+
case actual: MethodType =>
693+
adaptFun((parent, cs), actual.paramInfos, actual.resType, expected, covariant, insertBox,
694+
(aargs1, ares1) =>
695+
actual.derivedLambdaType(paramInfos = aargs1, resType = ares1))
696+
case actual @ RefinedType(p, nme, rinfo: PolyType) if defn.isFunctionOrPolyType(actual) =>
697+
adaptTypeFun((parent, cs), rinfo.resType, expected, covariant, insertBox,
698+
ares1 =>
699+
val rinfo1 = rinfo.derivedLambdaType(rinfo.paramNames, rinfo.paramInfos, ares1)
700+
val actual1 = actual.derivedRefinedType(p, nme, rinfo1)
701+
actual1
702+
)
659703
case _ =>
660704
(parent, cs)
661705
}
@@ -674,7 +718,7 @@ class CheckCaptures extends Recheck, SymTransformer:
674718
// Disallow future addition of `*` to `criticalSet`.
675719
criticalSet.disallowRootCapability { () =>
676720
report.error(
677-
em"""$cs $parent cannot be box-converted to $expected
721+
em"""$actualIsBoxed $cs $parent cannot be box-converted to $expected
678722
|since one of their capture sets contains the root capability `*`""",
679723
pos)
680724
}

0 commit comments

Comments
 (0)