From 2d8849a77909e61ad0512973d10261751b19d520 Mon Sep 17 00:00:00 2001 From: Aleksander Boruch-Gruszecki Date: Fri, 12 Mar 2021 11:25:32 +0100 Subject: [PATCH] GADTs: widen only top-level variant params --- .../dotc/core/PatternTypeConstrainer.scala | 18 ++++++++---------- tests/neg/i11565.gadt.scala | 16 ++++++++++++++++ tests/neg/invariant-gadt.scala | 4 ++++ 3 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 tests/neg/i11565.gadt.scala diff --git a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala index c20b2868726a..33b764680df0 100644 --- a/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala +++ b/compiler/src/dotty/tools/dotc/core/PatternTypeConstrainer.scala @@ -189,16 +189,14 @@ trait PatternTypeConstrainer { self: TypeComparer => case _ => false } - def widenVariantParams = new TypeMap { - def apply(tp: Type) = mapOver(tp) match { - case tp @ AppliedType(tycon, args) => - val args1 = args.zipWithConserve(tycon.typeParams)((arg, tparam) => - if (tparam.paramVarianceSign != 0) TypeBounds.empty else arg - ) - tp.derivedAppliedType(tycon, args1) - case tp => - tp - } + def widenVariantParams(tp: Type) = tp match { + case tp @ AppliedType(tycon, args) => + val args1 = args.zipWithConserve(tycon.typeParams)((arg, tparam) => + if (tparam.paramVarianceSign != 0) TypeBounds.empty else arg + ) + tp.derivedAppliedType(tycon, args1) + case tp => + tp } val widePt = diff --git a/tests/neg/i11565.gadt.scala b/tests/neg/i11565.gadt.scala new file mode 100644 index 000000000000..8c58927904b5 --- /dev/null +++ b/tests/neg/i11565.gadt.scala @@ -0,0 +1,16 @@ +@main def test: Unit = { + trait TyCon[+A] + trait S[T] + trait P[T] extends S[TyCon[T]] { + def consume(t: T): Unit + } + + def patmat(s: S[TyCon[Int]]) = s match { + case p: P[t] => + p.consume("Hi") // error + } + + patmat(new P[Int] { + override def consume(t: Int): Unit = t + 1 + }) +} diff --git a/tests/neg/invariant-gadt.scala b/tests/neg/invariant-gadt.scala index ac335f57743f..b6c6978ff723 100644 --- a/tests/neg/invariant-gadt.scala +++ b/tests/neg/invariant-gadt.scala @@ -1,6 +1,10 @@ object `invariant-gadt` { case class Invariant[T](value: T) + def soundInPrinciple[T](i: Invariant[T]) : Int = i match { + case _: Invariant[Int] => i.value + } + def unsound0[T](t: T): T = Invariant(t) match { case Invariant(_: Int) => (0: Any) // error