Skip to content

Commit f00ac95

Browse files
committed
Use constrainPatternType also for unapply patterns
1 parent 7bac0a2 commit f00ac95

File tree

5 files changed

+20
-5
lines changed

5 files changed

+20
-5
lines changed

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
933933
* - If a type proxy P is not a reference to a class, P's supertype is in G
934934
*/
935935
def isSubTypeOfParent(subtp: Type, tp: Type)(implicit ctx: Context): Boolean =
936-
if (subtp <:< tp) true
936+
if (constrainPatternType(subtp, tp)) true
937937
else tp match {
938938
case tp: TypeRef if tp.symbol.isClass => isSubTypeOfParent(subtp, tp.firstParent)
939939
case tp: TypeProxy => isSubTypeOfParent(subtp, tp.superType)

compiler/src/dotty/tools/dotc/typer/Inferencing.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ object Inferencing {
186186
* Invariant refinement can be assumed if `PatternType`'s class(es) are final or
187187
* case classes (because of `RefChecks#checkCaseClassInheritanceInvariant`).
188188
*/
189-
def constrainPatternType(tp: Type, pt: Type)(implicit ctx: Context) = {
189+
def constrainPatternType(tp: Type, pt: Type)(implicit ctx: Context): Boolean = {
190190
def refinementIsInvariant(tp: Type): Boolean = tp match {
191191
case tp: ClassInfo => tp.cls.is(Final) || tp.cls.is(Case)
192192
case tp: TypeProxy => refinementIsInvariant(tp.underlying)
@@ -207,7 +207,7 @@ object Inferencing {
207207
}
208208

209209
val widePt = if (ctx.scala2Mode || refinementIsInvariant(tp)) pt else widenVariantParams(pt)
210-
(tp <:< widePt)(ctx.addMode(Mode.GADTflexible))
210+
tp <:< widePt
211211
}
212212

213213
/** The list of uninstantiated type variables bound by some prefix of type `T` which

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ class Typer extends Namer
569569
def typedTpt = checkSimpleKinded(typedType(tree.tpt))
570570
def handlePattern: Tree = {
571571
val tpt1 = typedTpt
572-
if (!ctx.isAfterTyper) constrainPatternType(tpt1.tpe, pt)
572+
if (!ctx.isAfterTyper) constrainPatternType(tpt1.tpe, pt)(ctx.addMode(Mode.GADTflexible))
573573
// special case for an abstract type that comes with a class tag
574574
tryWithClassTag(ascription(tpt1, isWildcard = true), pt)
575575
}

tests/neg/i3989b.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ object Test extends App {
33
case class B[+X](val x: X) extends A[X]
44
class C[+X](x: Any) extends B[Any](x) with A[X] // error
55
def f(a: A[Int]): Int = a match {
6-
case a: B[_] => a.x
6+
case B(i) => i
77
case _ => 0
88
}
99
f(new C[Int]("foo"))

tests/neg/i3989c.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import scala.Option
2+
object Test extends App {
3+
trait A[+X]
4+
class B[+X](val x: X) extends A[X]
5+
object B {
6+
def unapply[X](b: B[X]): Option[X] = Some(b.x)
7+
}
8+
9+
class C[+X](x: Any) extends B[Any](x) with A[X]
10+
def f(a: A[Int]): Int = a match {
11+
case B(i) => i // error
12+
case _ => 0
13+
}
14+
f(new C[Int]("foo"))
15+
}

0 commit comments

Comments
 (0)