diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-10-01 08:51:36 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-10-01 09:00:04 +1000 |
commit | 84d46719a9ab3caa7ff46af4630d75f8c407c3d2 (patch) | |
tree | 467b70c4c27fed537fa7b2a014cb16b520aba609 | |
parent | a52db7f1639c6d48eaa64ae609385a60467fd566 (diff) | |
download | scala-84d46719a9ab3caa7ff46af4630d75f8c407c3d2.tar.gz scala-84d46719a9ab3caa7ff46af4630d75f8c407c3d2.tar.bz2 scala-84d46719a9ab3caa7ff46af4630d75f8c407c3d2.zip |
SI-8869 Prevent ill-kindedness in type lambdas
When type checking an type application, the arguments are allowed
to be of kinds other than *. This leniency is controlled by the
`ContextMode` bit `TypeConstructorAllowed`.
(More fine grained checking of matching arity a bounds of type
constructors is deferred until the refchecks phase to avoid
cycles during typechecking.)
However, this bit is propagated to child contexts, which means
that we fail to report this error in the lexical context marked
here:
T[({type x = Option}#x)]
`-------------'
This commit resets this bit to false in any child context
relates to a different tree from its parent.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 2 | ||||
-rw-r--r-- | test/files/neg/t8869.check | 7 | ||||
-rw-r--r-- | test/files/neg/t8869.scala | 10 |
3 files changed, 19 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index a79f162140..eb29ccf4e1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -480,6 +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 + registerContext(c.asInstanceOf[analyzer.Context]) debuglog("[context] ++ " + c.unit + " / " + tree.summaryString) c diff --git a/test/files/neg/t8869.check b/test/files/neg/t8869.check new file mode 100644 index 0000000000..40b8570f9f --- /dev/null +++ b/test/files/neg/t8869.check @@ -0,0 +1,7 @@ +t8869.scala:5: error: class Option takes type parameters + def value: TC[({type l1[x] = Option})#l1] = ??? // error not reported! + ^ +t8869.scala:7: error: class Option takes type parameters + type l2[x] = Option // error correctly reported + ^ +two errors found diff --git a/test/files/neg/t8869.scala b/test/files/neg/t8869.scala new file mode 100644 index 0000000000..0c7f0c9451 --- /dev/null +++ b/test/files/neg/t8869.scala @@ -0,0 +1,10 @@ +class TC[T[_]] { + def identity[A](a: T[A]): T[A] = a +} +object Test { + def value: TC[({type l1[x] = Option})#l1] = ??? // error not reported! + + type l2[x] = Option // error correctly reported + def value1: TC[l2] = ??? +} + |