summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala11
-rw-r--r--test/files/neg/bug1275.check6
-rw-r--r--test/files/neg/bug1275.scala13
-rw-r--r--test/files/pos/t3419/B_1.scala3
-rw-r--r--test/files/pos/t3419/C_2.scala3
5 files changed, 28 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 22a1bee9b2..b3ea178aaa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1067,6 +1067,17 @@ trait Namers { self: Analyzer =>
case tp =>
tp
}
+
+ // see neg/bug1275, #3419
+ // used to do a rudimentary kind check here to ensure overriding in refinements
+ // doesn't change a type member's arity (number of type parameters),
+ // e.g. trait T { type X[A] }; type S = T{type X}; val x: S
+ // X in x.X[A] will get rebound to the X in the refinement, which does not take any type parameters
+ // this mismatch does not crash the compiler (anymore), but leads to weird type errors,
+ // as x.X[A] will become NoType internally
+ // it's not obvious the errror refers to the X in the refinement and not the original X
+ // however, separate compilation requires the symbol info to be loaded to do this check,
+ // but loading the info will probably lead to spurious cyclic errors --> omit the check
polyType(tparamSyms, tp)
}
diff --git a/test/files/neg/bug1275.check b/test/files/neg/bug1275.check
index 40c5d79d27..6ee8365796 100644
--- a/test/files/neg/bug1275.check
+++ b/test/files/neg/bug1275.check
@@ -1,6 +1,6 @@
-bug1275.scala:8: error: type mismatch;
+bug1275.scala:11: error: type mismatch;
found : xs.MyType[a]
required: s
- = xs f // xs: s <: Seq[a]{type MyType <: s }
- ^
+ = xs f
+ ^
one error found
diff --git a/test/files/neg/bug1275.scala b/test/files/neg/bug1275.scala
index 769156fff2..1175b30763 100644
--- a/test/files/neg/bug1275.scala
+++ b/test/files/neg/bug1275.scala
@@ -1,12 +1,15 @@
object Test {
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 // xs: s <: Seq[a]{type MyType <: s }
- // xs.f : xs.MyType[a] <: Seq[a]
- // ill-formed type in bound for s: Seq[a] { type MyType <: s }
- // refinements aren't checked -- should they?
+ // illegal abstract type member refinement: changes the arity of MyType
+ // the error is pretty strange, since the compiler forms the illegal type xs.MyType[a] anyway
+ def span[a, s <: Seq[a] { type MyType/*look ma, no type parameters!*/ <: s } ](xs: s): s
+ = xs f
+// ^
+// found : xs.MyType[a]
+// required: s
} \ No newline at end of file
diff --git a/test/files/pos/t3419/B_1.scala b/test/files/pos/t3419/B_1.scala
new file mode 100644
index 0000000000..a8ec7edba4
--- /dev/null
+++ b/test/files/pos/t3419/B_1.scala
@@ -0,0 +1,3 @@
+trait T[A,B] {
+ type X[a <: A, b <: B] <: B
+} \ No newline at end of file
diff --git a/test/files/pos/t3419/C_2.scala b/test/files/pos/t3419/C_2.scala
new file mode 100644
index 0000000000..da721d2c31
--- /dev/null
+++ b/test/files/pos/t3419/C_2.scala
@@ -0,0 +1,3 @@
+object F {
+ type S = T[Any,Int] {type X[N <: Int, Acc <: Int] = Acc}
+} \ No newline at end of file