Skip to content

Commit 06b978a

Browse files
committed
Try to disallow illegal match types in F-bounds
This is the minimum extra check needed to avoid loops after the inference changes in this PR and is incomplete, see test case.
1 parent 586fbcf commit 06b978a

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,22 @@ trait ConstraintHandling[AbstractContext] {
8787

8888
protected def addOneBound(param: TypeParamRef, bound: Type, isUpper: Boolean)(using AbstractContext): Boolean =
8989
if !constraint.contains(param) then true
90-
else if !isUpper && param.occursIn(bound)
91-
// We don't allow recursive lower bounds when defining a type,
92-
// so we shouldn't allow them as constraints either.
90+
else if
91+
bound.existsPart {
92+
case `param` =>
93+
// We don't allow recursive lower bounds when defining a type,
94+
// so we shouldn't allow them as constraints either.
95+
!isUpper
96+
case AppliedType(tycon: TypeRef, args) if tycon.info.isInstanceOf[MatchAlias] =>
97+
// FIXME: this is incomplete, see tests/pos/type-match-fbounds.scala
98+
args.exists {
99+
case `param` => true
100+
case tp: TypeVar => tp.origin eq param
101+
case _ => false
102+
}
103+
case _ => false
104+
}
105+
then
93106
false
94107
else
95108
val oldBounds @ TypeBounds(lo, hi) = constraint.nonParamBounds(param)

tests/neg/type-match-fbounds.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class A {
2+
type Foo[T] = T match {
3+
case Int => String
4+
case T => T
5+
}
6+
7+
// FIXME: These cases are not disallowed currently and cause
8+
// infinite loops
9+
/*
10+
def a1[T <: (T match {
11+
case Int => String
12+
case T => T
13+
})]: T = ???
14+
a1
15+
16+
def a2[T, U >: T <: (T match {
17+
case Int => String
18+
case T => T
19+
})]: T = ???
20+
a2
21+
22+
def a3[T <: Foo[T]]: T = ???
23+
a3
24+
*/
25+
26+
def a4[T, U >: T <: Foo[T]]: T = ???
27+
a4 // error
28+
}

0 commit comments

Comments
 (0)