Skip to content

Commit

Permalink
Fix variance computation for parameterized type aliases
Browse files Browse the repository at this point in the history
The variance of a type alias was taken to be the variance of its
right-hand side, but that doesn't make sense for a parameterized type
alias which is free to appear in any position: variance checking should
only kick in when it is applied to something.

It was possible to work around this by using a type lambda instead of a
type alias, cats just had to do that: typelevel/cats#3264
  • Loading branch information
smarter committed Jan 21, 2020
1 parent f0e9c40 commit 983cd85
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/reflect/scala/reflect/internal/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3076,7 +3076,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
extends TypeSymbol(initOwner, initPos, initName) {
type TypeOfClonedSymbol = TypeSymbol
override def variance = if (isLocalToThis) Bivariant else info.typeSymbol.variance
override def variance =
// A non-applied parameterized type alias can appear in any variance position
if (typeParams.nonEmpty)
Invariant
else if (isLocalToThis)
Bivariant
else
info.typeSymbol.variance

override def isContravariant = variance.isContravariant
override def isCovariant = variance.isCovariant
final override def isAliasType = true
Expand Down
7 changes: 7 additions & 0 deletions test/files/neg/variance-alias.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
trait Inv[A]

class X[+T] {
type Id[+A] = A
val a: Inv[({type L[+X] = X})#L[T]] = new Inv[({type L[+X] = X})#L[T]] {} // error
val b: Inv[Id[T]] = new Inv[Id[T]] {} // error
}
6 changes: 6 additions & 0 deletions test/files/pos/variance-alias.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
trait Tc[F[_]]
object X {
type Id[+A] = A
val a: Tc[({type L[+X] = X})#L] = new Tc[({type L[+X] = X})#L] {} // ok, therefore the following should be to:
val b: Tc[Id] = new Tc[Id] {} // ok
}

0 comments on commit 983cd85

Please sign in to comment.