Skip to content

Commit b6b2d12

Browse files
committed
Fix cycle detection for type aliases with wildcard arguments
#15507 escaped the cycle detector since when the right hand side was typechecked, the type constructor _NestedSet2's type was `[X] <: Any` and the constructor was marked Provisional. Fixes #15507
1 parent 0059d1d commit b6b2d12

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,12 +2027,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
20272027
var checkedArgs = preCheckKinds(args1, paramBounds)
20282028
// check that arguments conform to bounds is done in phase PostTyper
20292029
val tycon = tpt1.symbol
2030-
if (tycon == defn.andType)
2031-
checkedArgs = checkedArgs.mapconserve(arg =>
2032-
checkSimpleKinded(checkNoWildcard(arg)))
2033-
else if (tycon == defn.orType)
2030+
if tycon == defn.andType || tycon == defn.orType then
20342031
checkedArgs = checkedArgs.mapconserve(arg =>
20352032
checkSimpleKinded(checkNoWildcard(arg)))
2033+
else if tycon.flagsUNSAFE.is(Provisional) then
2034+
// A type with Provisional flag is either an alias or abstract type.
2035+
// If it is an alias type, it would mean the type is cyclic
2036+
// If it is an abstract type, it would mean the type is an irreducible
2037+
// application of a higher-kinded type to a wildcard argument.
2038+
// Either way, the wildcard argument is illegal.
2039+
// The early test here is needed, so that we do not accidentally reduce
2040+
// an application of a Provisional type away so that the type constructor
2041+
// is no longer present on the roght hand side. See neg/i15507.scala.
2042+
checkedArgs = checkedArgs.mapconserve(checkNoWildcard)
20362043
else if tycon == defn.throwsAlias
20372044
&& checkedArgs.length == 2
20382045
&& checkedArgs(1).tpe.derivesFrom(defn.RuntimeExceptionClass)

tests/neg/i15507.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object TestNested:
2+
type _NestedSet1[X] = Set[_NestedSet1[?]] // error // error
3+
type _NestedSet2[X] <: Set[_NestedSet2[?]] // error
4+
type _NestedSet3[X] <: Set[_NestedSet3[X]] // ok
5+
type _NestedSet4[X] >: Set[_NestedSet4[X]] // error
6+
type _NestedSet5[X] = Set[_NestedSet5[X]] // error
7+
type _NestedSet6[X] = Set[_NestedSet6[Int]] // error
8+
9+
type _NestedList1[X] = List[_NestedList1[?]] // error // error
10+
type _NestedList2[X] <: List[_NestedList2[?]] // error
11+
type _NestedList3[X] <: List[_NestedList3[X]] // ok
12+
type _NestedList4[X] >: List[_NestedList4[X]] // error
13+
type _NestedList5[X] = List[_NestedList5[X]] // error
14+
type _NestedList6[X] = List[_NestedList6[Int]] // error
15+

0 commit comments

Comments
 (0)