Skip to content

Commit

Permalink
Merge pull request #9417 from joroKr21/hk-skolems
Browse files Browse the repository at this point in the history
Correct bounds for higher-kinded GADT skolems
  • Loading branch information
diesalbla committed Jan 6, 2021
2 parents 2e79383 + cd13abc commit b049775
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 10 deletions.
12 changes: 6 additions & 6 deletions src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
Expand Up @@ -195,16 +195,16 @@ trait PatternTypers {

def skolems = try skolemBuffer.toList finally skolemBuffer.clear()
def apply(tp: Type): Type = mapOver(tp) match {
case tp @ TypeRef(NoPrefix, tpSym, Nil) if eligible(tpSym) =>
val bounds = (
if (variance.isInvariant) tpSym.tpeHK.bounds
else if (variance.isPositive) TypeBounds.upper(tpSym.tpeHK)
else TypeBounds.lower(tpSym.tpeHK)
case TypeRef(NoPrefix, tpSym, Nil) if eligible(tpSym) =>
val bounds = genPolyType(tpSym.typeParams,
if (variance.isInvariant) tpSym.tpe.bounds
else if (variance.isPositive) TypeBounds.upper(tpSym.tpe)
else TypeBounds.lower(tpSym.tpe)
)
// origin must be the type param so we can deskolemize
val skolem = context.owner.newGADTSkolem(freshTypeName("?" + tpSym.name), tpSym, bounds)
skolemBuffer += skolem
logResult(s"Created gadt skolem $skolem: ${skolem.tpe_*} to stand in for $tpSym")(skolem.tpe_*)
logResult(s"Created gadt skolem $skolem: ${skolem.tpeHK} to stand in for $tpSym")(skolem.tpeHK)
case tp1 => tp1
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/reflect/scala/reflect/internal/Types.scala
Expand Up @@ -2438,7 +2438,7 @@ trait Types


// interpret symbol's info in terms of the type's prefix and type args
protected def relativeInfo: Type = appliedType(sym.info.asSeenFrom(pre, sym.owner), argsOrDummies)
protected def relativeInfo: Type = appliedType(sym.info.asSeenFrom(pre, sym.owner), args)

// @M: propagate actual type params (args) to `tp`, by replacing
// formal type parameters with actual ones. If tp is higher kinded,
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/hk-existential-lb.check
@@ -1,7 +1,7 @@
hk-existential-lb.scala:5: error: type mismatch;
found : Functor[Option]
required: Functor[_[x] >: List[x]]
Note: Option <: Any, but class Functor is invariant in type F.
Note: Option <: [x]Any, but class Functor is invariant in type F.
You may wish to define F as +F instead. (SLS 4.5)
val someF: Functor[F] forSome { type F[x] >: List[x] } = new Functor[Option]
^
Expand Down
33 changes: 33 additions & 0 deletions test/files/pos/t12295.scala
@@ -0,0 +1,33 @@
object Test {
sealed trait Foo[+A] // sealed or not doesn't matter
case class ImplA[A](a: A) extends Foo[A]
case class ImplAny[A](a: Any) extends Foo[A]

trait Bar[+G[_]] // must be covariant

def err[F[_]](): Unit = {
val x: Foo[Foo[Bar[F]]] = ???

x match {
case ImplAny(ImplAny(_)) => ???
case ImplAny(ImplA(_)) => ???
case ImplA(_) => ???
case ImplAny(_) => ???
case _ => ???
}

x match {
case ImplA(ImplA(_)) => ???
case ImplA(ImplAny(_)) => ???
case ImplA(y) => y.toString
case ImplA(y) => y match {
case ImplA(_) => ???
case _ => ???
}
case ImplA(y) => y
case _ => ???
}

()
}
}
4 changes: 2 additions & 2 deletions test/files/run/repl-kind.check
Expand Up @@ -14,8 +14,8 @@ Either's kind is F[+A1,+A2]
This is a type constructor: a 1st-order-kinded type.

scala> :k -v scala.collection.SortedMapOps
scala.collection.SortedMapOps's kind is X[K,+V,+CC[X,Y] <: scala.collection.Map[X,Y] with scala.collection.SortedMapOps[X, Y, CC, _],+C <: scala.collection.SortedMapOps[K,V,CC,C]]
* -> * -(+)-> (* -> * -> *(scala.collection.Map[X,Y] with scala.collection.SortedMapOps[X, Y, CC, _])) -(+)-> *(scala.collection.SortedMapOps[K,V,CC,C]) -(+)-> *
scala.collection.SortedMapOps's kind is X[K,+V,+CC[X,Y] <: [X, Y]scala.collection.Map[X,Y] with scala.collection.SortedMapOps[X, Y, CC, _],+C <: scala.collection.SortedMapOps[K,V,CC,C]]
* -> * -(+)-> (* -> * -> *([X, Y]scala.collection.Map[X,Y] with scala.collection.SortedMapOps[X, Y, CC, _])) -(+)-> *(scala.collection.SortedMapOps[K,V,CC,C]) -(+)-> *
This is a type constructor that takes type constructor(s): a higher-kinded type.

scala> :kind -v Tuple2
Expand Down

0 comments on commit b049775

Please sign in to comment.