Skip to content

Commit e2b51a9

Browse files
committed
Fix underlying problem of box mismatches
The neg tests are now pos tests. I kept the special error message for better diagnosis if the mismatch arises elsewhere, and added a sentence that this could be an implementation problem.
1 parent 39b904d commit e2b51a9

File tree

5 files changed

+22
-31
lines changed

5 files changed

+22
-31
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,8 @@ object CaptureSet:
13881388
trailing:
13891389
val (boxed, unboxed) =
13901390
if cs.tp1.isBoxedCapturing then (cs.tp1, cs.tp2) else (cs.tp2, cs.tp1)
1391-
i"${cs.tp1} does not conform to ${cs.tp2} because $boxed is boxed but $unboxed is not"
1391+
i"""${cs.tp1} does not conform to ${cs.tp2} because $boxed is boxed but $unboxed is not.
1392+
|This could be an error in the capture checker implementation."""
13921393
case _ =>
13931394
def why =
13941395
val reasons = cs.elems.toList.collect:

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,10 +550,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
550550
|| !ctx.mode.is(Mode.CheckBoundsOrSelfType) && tp1.isAlwaysPure
551551
|| parent1.isSingleton && refs1.elems.forall(parent1 eq _)
552552
then
553+
def remainsBoxed1 = parent1.isBoxedCapturing || parent1.dealias.match
554+
case parent1: TypeRef =>
555+
parent1.superType.isBoxedCapturing
556+
// When comparing a type parameter with boxed upper bound on the left
557+
// we should not strip the box on the right. See i24543.scala.
558+
case _ =>
559+
false
553560
val tp2a =
554-
if tp1.isBoxedCapturing && !parent1.isBoxedCapturing
555-
then tp2.unboxed
556-
else tp2
561+
if tp1.isBoxedCapturing && !remainsBoxed1 then tp2.unboxed else tp2
557562
recur(parent1, tp2a)
558563
else thirdTry
559564
compareCapturing
@@ -2916,7 +2921,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
29162921
subc
29172922
&& (tp1.isBoxedCapturing == tp2.isBoxedCapturing
29182923
|| refs1.subCaptures(CaptureSet.EmptyOfBoxed(tp1, tp2), makeVarState()))
2919-
2924+
29202925
protected def logUndoAction(action: () => Unit) =
29212926
undoLog += action
29222927

tests/neg-custom-args/captures/i24543.check

Lines changed: 0 additions & 24 deletions
This file was deleted.

tests/neg-custom-args/captures/i24543.scala renamed to tests/pos-custom-args/captures/i24543.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ class Ref
44
case class Box[T](elem: T)
55

66
def h1[T <: Ref^](x: Box[T]): Unit =
7-
val y: (Ref^, Int) = (x.elem, 1) // error
7+
val y: (Ref^, Int) = (x.elem, 1) // was error
88

9-
def h2[T <: Ref^](x: List[T]): (Ref^, Int) = (x.head, 1) // error
9+
def h2[T <: Ref^](x: List[T]): (Ref^, Int) = (x.head, 1) // was error
1010

1111

1212

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.language.experimental.captureChecking
2+
class Ref
3+
case class Box[+T](elem: T)
4+
5+
def test1(a: Ref^): Unit =
6+
def hh[T <: Ref^{a}](x: Box[T]): Unit =
7+
val y: (Ref^{a}, Int) = (x.elem, 1)
8+
val z = (x.elem, 1)
9+
val _: (Ref^{a}, Int) = z

0 commit comments

Comments
 (0)