diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 15 | ||||
-rw-r--r-- | test/files/neg/variances.check | 19 | ||||
-rw-r--r-- | test/files/neg/variances.scala | 29 | ||||
-rw-r--r-- | test/files/pos/t3272.scala | 8 |
4 files changed, 48 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 045614e773..54b711cebc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -951,17 +951,20 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R override def traverse(tree: Tree) { tree match { - case ClassDef(_, _, _, _) | - TypeDef(_, _, _, _) => + case ClassDef(_, _, _, _) | TypeDef(_, _, _, _) => validateVariance(tree.symbol) super.traverse(tree) // ModuleDefs need not be considered because they have been eliminated already case ValDef(_, _, _, _) => - validateVariance(tree.symbol) + if (!tree.symbol.hasLocalFlag) + validateVariance(tree.symbol) case DefDef(_, _, tparams, vparamss, _, _) => - validateVariance(tree.symbol) - traverseTrees(tparams) - traverseTreess(vparamss) + // No variance check for object-private/protected methods/values. + if (!tree.symbol.hasLocalFlag) { + validateVariance(tree.symbol) + traverseTrees(tparams) + traverseTreess(vparamss) + } case Template(_, _, _) => super.traverse(tree) case _ => diff --git a/test/files/neg/variances.check b/test/files/neg/variances.check index dc72b05e1e..0643e533b7 100644 --- a/test/files/neg/variances.check +++ b/test/files/neg/variances.check @@ -1,16 +1,19 @@ variances.scala:4: error: covariant type A occurs in contravariant position in type test.Vector[A] of value x - def append(x: Vector[A]): Vector[A] + def append(x: Vector[A]): Vector[A] ^ -variances.scala:14: error: covariant type A occurs in contravariant position in type A of value a - private[this] def setA(a : A) = this.a = a - ^ -variances.scala:16: error: covariant type A occurs in invariant position in supertype test.C[A] of object Baz +variances.scala:18: error: covariant type A occurs in contravariant position in type A of value a + private def setA3(a : A) = this.a = a + ^ +variances.scala:19: error: covariant type A occurs in contravariant position in type A of value a + protected def setA4(a : A) = this.a = a + ^ +variances.scala:21: error: covariant type A occurs in invariant position in supertype test.C[A] of object Baz object Baz extends C[A] ^ -variances.scala:63: error: covariant type A occurs in contravariant position in type => test.Covariant.T[A]{val m: A => A} of value x +variances.scala:74: error: covariant type A occurs in contravariant position in type => test.Covariant.T[A]{val m: A => A} of value x val x: T[A] { ^ -variances.scala:79: error: covariant type T occurs in contravariant position in type => test.TestAlias.B[C.this.A] of method foo +variances.scala:90: error: covariant type T occurs in contravariant position in type => test.TestAlias.B[C.this.A] of method foo def foo: B[A] ^ -5 errors found +6 errors found diff --git a/test/files/neg/variances.scala b/test/files/neg/variances.scala index 726bc35270..10ca111cd0 100644 --- a/test/files/neg/variances.scala +++ b/test/files/neg/variances.scala @@ -1,7 +1,7 @@ package test trait Vector[+A] { - def append(x: Vector[A]): Vector[A] + def append(x: Vector[A]): Vector[A] private[this] def append3(x: Vector[A]): Vector[A] = append(x) } @@ -11,19 +11,27 @@ object Covariant { class Foo[+A] { private[this] var a : A = _ def getA : A = a - private[this] def setA(a : A) = this.a = a - + // allowed + private[this] def setA1(a : A) = this.a = a + protected[this] def setA2(a : A) = this.a = a + // forbidden + private def setA3(a : A) = this.a = a + protected def setA4(a : A) = this.a = a + object Baz extends C[A] trait Convert[B] { def b2a(b : B) : A - def doit(b : B) = setA(b2a(b)) + def doit1(b : B) = setA1(b2a(b)) + def doit2(b : B) = setA2(b2a(b)) + def doit3(b : B) = setA3(b2a(b)) + def doit4(b : B) = setA4(b2a(b)) } } class Foo2[+A] { private[this] var a : A = _ def getA : A = a - private[this] def setA(a : A) = this.a = a - + private[this] def setA(a : A) = this.a = a + { trait Convert[B] { def b2a(b : B) : A @@ -35,8 +43,8 @@ object Covariant { class Foo3[+A] { private[this] var a : A = _ def getA : A = a - private[this] def setA(a : A) = this.a = a - + private[this] def setA(a : A) = this.a = a + private[this] trait Convert[B] { def b2a(b : B) : A def doit(b : B) = setA(b2a(b)) @@ -54,7 +62,10 @@ object Covariant { } def main(args : Array[String]) { val test = new Test - test.c.doit(test.b) + test.c.doit1(test.b) + test.c.doit2(test.b) + test.c.doit3(test.b) + test.c.doit4(test.b) val x : java.lang.Character = test.a.getA Console.println("XXX " + x) } diff --git a/test/files/pos/t3272.scala b/test/files/pos/t3272.scala new file mode 100644 index 0000000000..8efd5ded2c --- /dev/null +++ b/test/files/pos/t3272.scala @@ -0,0 +1,8 @@ +trait A { + trait C[+T] { + protected[this] def f(t: T) {} + } + trait D[T] extends C[T] { + def g(t: T) { f(t) } + } +} |