summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2007-08-22 13:46:38 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2007-08-22 13:46:38 +0000
commit20caac2baca22cd3cb71a7f21da5703e4ca6f09a (patch)
treef234bd36e7c14e362d2d5d87007334ad96720c19
parente69edec6c715240cf71f4a555232ea18cd21e19f (diff)
downloadscala-20caac2baca22cd3cb71a7f21da5703e4ca6f09a.tar.gz
scala-20caac2baca22cd3cb71a7f21da5703e4ca6f09a.tar.bz2
scala-20caac2baca22cd3cb71a7f21da5703e4ca6f09a.zip
fixed 1275 by adding minimal early check to Nam...
fixed 1275 by adding minimal early check to Namers so that overriding of type members in refinements cannot change number of type parameters (in principle the full overriding checks should be performed at a later point, when they don't cause cyclicity errors -- this is TODO)
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala19
-rw-r--r--test/files/neg/bug1275.check4
-rw-r--r--test/files/neg/bug1275.scala14
3 files changed, 36 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 2e5ab49907..e82252c2ee 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -671,7 +671,24 @@ trait Namers { self: Analyzer =>
TypeBounds(AllClass.tpe, AnyClass.tpe)
case tp => tp
}
- parameterizedType(tparamSyms, tp) //@M
+
+ def verifyOverriding(other: Symbol): Boolean = {
+ if(other.unsafeTypeParams.length != tparamSyms.length) {
+ context.error(tpsym.pos,
+ "The kind of "+tpsym.keyString+" "+tpsym.varianceString + tpsym.nameString+
+ " does not conform to the expected kind of " + other.defString + other.locationString + ".")
+ false
+ } else true
+ }
+
+ // @M: make sure overriding in refinements respects rudimentary kinding
+ // have to do this early, as otherwise we might get crashes: (see neg/bug1275.scala)
+ // suppose some parameterized type member is overridden by a type member w/o params,
+ // then appliedType will be called on a type that does not expect type args --> crash
+ if (tpsym.owner.isRefinementClass && // only needed in refinements
+ !tpsym.allOverriddenSymbols.forall{verifyOverriding(_)})
+ ErrorType
+ else parameterizedType(tparamSyms, tp)
}
def typeSig(tree: Tree): Type = {
diff --git a/test/files/neg/bug1275.check b/test/files/neg/bug1275.check
new file mode 100644
index 0000000000..6ff92a7823
--- /dev/null
+++ b/test/files/neg/bug1275.check
@@ -0,0 +1,4 @@
+bug1275.scala:13: error: The kind of type MyType does not conform to the expected kind of type MyType[+t] <: TestCovariance.this.Seq[t] in trait Seq.
+ def span[a, s <: Seq[a] { type MyType <: s } ](xs: s): s = xs f
+ ^
+one error found
diff --git a/test/files/neg/bug1275.scala b/test/files/neg/bug1275.scala
new file mode 100644
index 0000000000..04c66400c8
--- /dev/null
+++ b/test/files/neg/bug1275.scala
@@ -0,0 +1,14 @@
+// tested using Scala compiler version 2.6.0-RC1 -- (c) 2002-2007 LAMP/EPFL
+
+// prompted by "Covariant return types" mailing list question
+object TestCovariance {
+
+ // see Type constructor polymorphism in http://www.scala-lang.org/docu/changelog.html
+ trait Seq[+t] {
+ type MyType[+t] <: Seq[t]
+
+ def f: MyType[t]
+ }
+
+ def span[a, s <: Seq[a] { type MyType <: s } ](xs: s): s = xs f
+}