summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/internal/Variances.scala10
-rw-r--r--test/files/neg/t8079a.check4
-rw-r--r--test/files/neg/t8079a.scala4
-rw-r--r--test/files/neg/variances.check2
-rw-r--r--test/files/pos/t8079b.scala7
-rw-r--r--test/pending/pos/t8079c.scala7
6 files changed, 29 insertions, 5 deletions
diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala
index 69bade55f1..0b964e81d5 100644
--- a/src/reflect/scala/reflect/internal/Variances.scala
+++ b/src/reflect/scala/reflect/internal/Variances.scala
@@ -53,8 +53,7 @@ trait Variances {
// return Bivariant if `sym` is local to a term
// or is private[this] or protected[this]
def isLocalOnly(sym: Symbol) = !sym.owner.isClass || (
- sym.isTerm // ?? shouldn't this be sym.owner.isTerm according to the comments above?
- && (sym.isLocalToThis || sym.isSuperAccessor) // super accessors are implicitly local #4345
+ (sym.isLocalToThis || sym.isSuperAccessor) // super accessors are implicitly local #4345
&& !escapedLocals(sym)
)
@@ -66,7 +65,7 @@ trait Variances {
* Initially the state is covariant, but it might change along the search.
*
* A local alias type is treated as Bivariant;
- * this is OK because we always expand aliases for variance checking.
+ * this is OK because such aliases are expanded for variance checking.
* However, for an alias which might be externally visible, we must assume Invariant,
* because there may be references to the type parameter that are not checked,
* leading to unsoundness (see SI-6566).
@@ -126,7 +125,7 @@ trait Variances {
tp match {
case _ if isUncheckedVariance(tp) =>
case _ if resultTypeOnly(tp) => this(tp.resultType)
- case TypeRef(_, sym, _) if sym.isAliasType => this(tp.normalize)
+ case TypeRef(_, sym, _) if shouldDealias(sym) => this(tp.normalize)
case TypeRef(_, sym, _) if !sym.variance.isInvariant => checkVarianceOfSymbol(sym) ; mapOver(tp)
case RefinedType(_, _) => withinRefinement(mapOver(tp))
case ClassInfoType(parents, _, _) => parents foreach this
@@ -138,6 +137,9 @@ trait Variances {
// than the result of the pattern match above, which normalizes types.
tp
}
+ private def shouldDealias(sym: Symbol): Boolean = {
+ sym.isAliasType && isLocalOnly(sym)
+ }
def validateDefinition(base: Symbol) {
val saved = this.base
this.base = base
diff --git a/test/files/neg/t8079a.check b/test/files/neg/t8079a.check
new file mode 100644
index 0000000000..6bbe78afa6
--- /dev/null
+++ b/test/files/neg/t8079a.check
@@ -0,0 +1,4 @@
+t8079a.scala:3: error: contravariant type I occurs in covariant position in type C.this.X of value b
+ def f2(b: X): Unit
+ ^
+one error found
diff --git a/test/files/neg/t8079a.scala b/test/files/neg/t8079a.scala
new file mode 100644
index 0000000000..4997ea282e
--- /dev/null
+++ b/test/files/neg/t8079a.scala
@@ -0,0 +1,4 @@
+trait C[-I] {
+ private[this] type X = C[I]
+ def f2(b: X): Unit
+}
diff --git a/test/files/neg/variances.check b/test/files/neg/variances.check
index cb1a60a632..3c1545a375 100644
--- a/test/files/neg/variances.check
+++ b/test/files/neg/variances.check
@@ -19,7 +19,7 @@ variances.scala:74: error: covariant type A occurs in contravariant position in
variances.scala:89: error: covariant type T occurs in invariant position in type T of type A
type A = T
^
-variances.scala:90: 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 A occurs in contravariant position in type => test.TestAlias.B[C.this.A] of method foo
def foo: B[A]
^
8 errors found
diff --git a/test/files/pos/t8079b.scala b/test/files/pos/t8079b.scala
new file mode 100644
index 0000000000..f3b7b78077
--- /dev/null
+++ b/test/files/pos/t8079b.scala
@@ -0,0 +1,7 @@
+trait F1[/* - */T, /* + */ R]
+
+object Test {
+ import scala.annotation.unchecked._
+ type VariantF1[-T, +R] = F1[T @uncheckedVariance, R @uncheckedVariance]
+ trait C[+T] { def foo: VariantF1[Any, T] }
+}
diff --git a/test/pending/pos/t8079c.scala b/test/pending/pos/t8079c.scala
new file mode 100644
index 0000000000..ae7f37e2bf
--- /dev/null
+++ b/test/pending/pos/t8079c.scala
@@ -0,0 +1,7 @@
+trait F1[/* - */T, /* + */ R]
+
+object Test {
+ import scala.annotation.unchecked._
+ private[this] type VariantF1[-T, +R] = F1[T @uncheckedVariance, R @uncheckedVariance]
+ trait C[+T] { def foo: VariantF1[Any, T] }
+}