Skip to content

Commit 64ae23f

Browse files
committed
SI-9008 Fix regression with higher kinded existentials
Allow a naked type constructor in an existential type if we are directly within a type application. Recently, 84d4671 changed nested context creation to avoid passing down the `TypeConstructorAllowed`, which led to missing kind errors in code like `type T[({type M = List})#M]`. However, when typechecking `T forSome { quantifiers }`, we create a nested context to represent the nested scope introduced for the quantifiers. But we need to propagate the `TypeConstructorAllowed` bit to the nested context to allow for higher kinded existentials. The enclosed tests show: - pos/t9008 well kinded application of an hk existential - neg/t9008 hk existential forbidden outside of type application - neg/t9008b kind error reported for hk existential Regressed in 84d4671.
1 parent 028420c commit 64ae23f

File tree

7 files changed

+26
-2
lines changed

7 files changed

+26
-2
lines changed

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ trait Contexts { self: Analyzer =>
480480
// SI-8245 `isLazy` need to skip lazy getters to ensure `return` binds to the right place
481481
c.enclMethod = if (isDefDef && !owner.isLazy) c else enclMethod
482482

483-
if (tree != outer.tree) c(TypeConstructorAllowed) = false
483+
if (tree != outer.tree)
484+
c(TypeConstructorAllowed) = false
484485

485486
registerContext(c.asInstanceOf[analyzer.Context])
486487
debuglog("[context] ++ " + c.unit + " / " + tree.summaryString)

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5207,7 +5207,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
52075207

52085208
def typedExistentialTypeTree(tree: ExistentialTypeTree) = {
52095209
val tree1 = typerWithLocalContext(context.makeNewScope(tree, context.owner)){
5210-
_.typedExistentialTypeTree(tree, mode)
5210+
typer =>
5211+
if (context.inTypeConstructorAllowed)
5212+
typer.context.withinTypeConstructorAllowed(typer.typedExistentialTypeTree(tree, mode))
5213+
else
5214+
typer.typedExistentialTypeTree(tree, mode)
52115215
}
52125216
checkExistentialsFeature(tree1.pos, tree1.tpe, "the existential type")
52135217
tree1

test/files/neg/t9008.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
t9008.scala:2: error: type M takes type parameters
2+
def x: List[M forSome { type M[_] }] = ???
3+
^
4+
one error found

test/files/neg/t9008.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test {
2+
def x: List[M forSome { type M[_] }] = ???
3+
}

test/files/neg/t9008b.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
t9008b.scala:2: error: type M takes type parameters
2+
type T = M forSome { type M[_] }
3+
^
4+
one error found

test/files/neg/t9008b.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test {
2+
type T = M forSome { type M[_] }
3+
}

test/files/pos/t9008.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
trait Monad[M[_]]
2+
3+
object Test {
4+
def x: Monad[M forSome { type M[_] }] = ???
5+
}

0 commit comments

Comments
 (0)