Skip to content

Commit a94a69c

Browse files
committed
Fix match type bounds checking problem
1 parent 5bba231 commit a94a69c

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -145,22 +145,26 @@ object Checking {
145145
val checker = new TypeTraverser:
146146
def traverse(tp: Type) =
147147
tp match
148-
case AppliedType(tycon, argTypes)
149-
if !(tycon.typeSymbol.is(JavaDefined) && ctx.compilationUnit.isJava)
150-
// Don't check bounds in Java units that refer to Java type constructors.
151-
// Scala is not obliged to do Java type checking and in fact i17763 goes wrong
152-
// if we attempt to check bounds of F-bounded mutually recursive Java interfaces.
153-
// Do check all bounds in Scala units and those bounds in Java units that
154-
// occur in applications of Scala type constructors.
155-
&& !isCaptureChecking || tycon.typeSymbol.is(CaptureChecked)
156-
// Don't check bounds when capture checking type constructors that were not
157-
// themselves capture checked. Since the type constructor could not foresee
158-
// possible capture sets, it's better to be lenient for backwards compatibility.
159-
=>
160-
checkAppliedType(
161-
untpd.AppliedTypeTree(TypeTree(tycon), argTypes.map(TypeTree(_)))
162-
.withType(tp).withSpan(tpt.span.toSynthetic),
163-
tpt)
148+
case tp @ AppliedType(tycon, argTypes) =>
149+
// Should the type be re-checked in the CC phase?
150+
// Exempted are types that are not themselves capture-checked.
151+
// Since the type constructor could not foresee possible capture sets,
152+
// it's better to be lenient for backwards compatibility.
153+
// Also exempted are match aliases. See tuple-ops.scala for an example that
154+
// would fail otherwise.
155+
def checkableUnderCC =
156+
tycon.typeSymbol.is(CaptureChecked) && !tp.isMatchAlias
157+
if !(tycon.typeSymbol.is(JavaDefined) && ctx.compilationUnit.isJava)
158+
// Don't check bounds in Java units that refer to Java type constructors.
159+
// Scala is not obliged to do Java type checking and in fact i17763 goes wrong
160+
// if we attempt to check bounds of F-bounded mutually recursive Java interfaces.
161+
// Do check all bounds in Scala units and those bounds in Java units that
162+
// occur in applications of Scala type constructors.
163+
&& (!isCaptureChecking || checkableUnderCC) then
164+
checkAppliedType(
165+
untpd.AppliedTypeTree(TypeTree(tycon), argTypes.map(TypeTree(_)))
166+
.withType(tp).withSpan(tpt.span.toSynthetic),
167+
tpt)
164168
case _ =>
165169
traverseChildren(tp)
166170
checker.traverse(tpt.tpe)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
sealed trait Tupp
2+
3+
case object EmptyTupp extends Tupp
4+
type EmptyTupp = EmptyTupp.type
5+
infix case class `*::`[H, T <: Tupp](h: H, t: T) extends Tupp
6+
7+
type Union[T <: Tupp] = T match
8+
case EmptyTupp => Nothing
9+
case h *:: t => h | Union[t]
10+
11+
type Map[T <: Tupp, F[_ <: Union[T]]] <: Tupp = T match
12+
case EmptyTupp => EmptyTupp
13+
case h *:: t => F[h] *:: Map[t, F]

0 commit comments

Comments
 (0)