diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-11-27 14:27:07 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-12-03 11:45:54 +1000 |
commit | 64ae23f6438054a08bebf1fa6af0f14d63cfc0ea (patch) | |
tree | 54083975022d0a4c17b53e369f7bd39f8e201c8f | |
parent | 028420cd80a2cf1127790fdd28088f6db575e8dd (diff) | |
download | scala-64ae23f6438054a08bebf1fa6af0f14d63cfc0ea.tar.gz scala-64ae23f6438054a08bebf1fa6af0f14d63cfc0ea.tar.bz2 scala-64ae23f6438054a08bebf1fa6af0f14d63cfc0ea.zip |
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.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 6 | ||||
-rw-r--r-- | test/files/neg/t9008.check | 4 | ||||
-rw-r--r-- | test/files/neg/t9008.scala | 3 | ||||
-rw-r--r-- | test/files/neg/t9008b.check | 4 | ||||
-rw-r--r-- | test/files/neg/t9008b.scala | 3 | ||||
-rw-r--r-- | test/files/pos/t9008.scala | 5 |
7 files changed, 26 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index b13f9e94cc..9a34e8dfed 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -480,7 +480,8 @@ trait Contexts { self: Analyzer => // SI-8245 `isLazy` need to skip lazy getters to ensure `return` binds to the right place c.enclMethod = if (isDefDef && !owner.isLazy) c else enclMethod - if (tree != outer.tree) c(TypeConstructorAllowed) = false + if (tree != outer.tree) + c(TypeConstructorAllowed) = false registerContext(c.asInstanceOf[analyzer.Context]) debuglog("[context] ++ " + c.unit + " / " + tree.summaryString) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 4d9a6a47ef..aaa75b5ee1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5207,7 +5207,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def typedExistentialTypeTree(tree: ExistentialTypeTree) = { val tree1 = typerWithLocalContext(context.makeNewScope(tree, context.owner)){ - _.typedExistentialTypeTree(tree, mode) + typer => + if (context.inTypeConstructorAllowed) + typer.context.withinTypeConstructorAllowed(typer.typedExistentialTypeTree(tree, mode)) + else + typer.typedExistentialTypeTree(tree, mode) } checkExistentialsFeature(tree1.pos, tree1.tpe, "the existential type") tree1 diff --git a/test/files/neg/t9008.check b/test/files/neg/t9008.check new file mode 100644 index 0000000000..c32bc41baf --- /dev/null +++ b/test/files/neg/t9008.check @@ -0,0 +1,4 @@ +t9008.scala:2: error: type M takes type parameters + def x: List[M forSome { type M[_] }] = ??? + ^ +one error found diff --git a/test/files/neg/t9008.scala b/test/files/neg/t9008.scala new file mode 100644 index 0000000000..c6a5389e42 --- /dev/null +++ b/test/files/neg/t9008.scala @@ -0,0 +1,3 @@ +object Test { + def x: List[M forSome { type M[_] }] = ??? +} diff --git a/test/files/neg/t9008b.check b/test/files/neg/t9008b.check new file mode 100644 index 0000000000..5e911fc138 --- /dev/null +++ b/test/files/neg/t9008b.check @@ -0,0 +1,4 @@ +t9008b.scala:2: error: type M takes type parameters + type T = M forSome { type M[_] } + ^ +one error found diff --git a/test/files/neg/t9008b.scala b/test/files/neg/t9008b.scala new file mode 100644 index 0000000000..58f9d0e8de --- /dev/null +++ b/test/files/neg/t9008b.scala @@ -0,0 +1,3 @@ +object Test { + type T = M forSome { type M[_] } +} diff --git a/test/files/pos/t9008.scala b/test/files/pos/t9008.scala new file mode 100644 index 0000000000..d11b8604f2 --- /dev/null +++ b/test/files/pos/t9008.scala @@ -0,0 +1,5 @@ +trait Monad[M[_]] + +object Test { + def x: Monad[M forSome { type M[_] }] = ??? +} |