Skip to content

Commit 9b326e5

Browse files
committed
Use constrainPatternType also for unapply patterns
1 parent d994307 commit 9b326e5

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
@@ -927,7 +927,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
927927
* - If a type proxy P is not a reference to a class, P's supertype is in G
928928
*/
929929
def isSubTypeOfParent(subtp: Type, tp: Type)(implicit ctx: Context): Boolean =
930-
if (subtp <:< tp) true
930+
if (constrainPatternType(subtp, tp)) true
931931
else tp match {
932932
case tp: TypeRef if tp.symbol.isClass => isSubTypeOfParent(subtp, tp.firstParent)
933933
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
@@ -185,7 +185,7 @@ object Inferencing {
185185
* Invariant refinement can be assumed if `PatternType`'s class(es) are final or
186186
* case classes (because of `RefChecks#checkCaseClassInheritanceInvariant`).
187187
*/
188-
def constrainPatternType(tp: Type, pt: Type)(implicit ctx: Context) = {
188+
def constrainPatternType(tp: Type, pt: Type)(implicit ctx: Context): Boolean = {
189189
def refinementIsInvariant(tp: Type): Boolean = tp match {
190190
case tp: ClassInfo => tp.cls.is(Final) || tp.cls.is(Case)
191191
case tp: TypeProxy => refinementIsInvariant(tp.underlying)
@@ -206,7 +206,7 @@ object Inferencing {
206206
}
207207

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

212212
/** 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
@@ -568,7 +568,7 @@ class Typer extends Namer
568568
def typedTpt = checkSimpleKinded(typedType(tree.tpt))
569569
def handlePattern: Tree = {
570570
val tpt1 = typedTpt
571-
if (!ctx.isAfterTyper) constrainPatternType(tpt1.tpe, pt)
571+
if (!ctx.isAfterTyper) constrainPatternType(tpt1.tpe, pt)(ctx.addMode(Mode.GADTflexible))
572572
// special case for an abstract type that comes with a class tag
573573
tryWithClassTag(ascription(tpt1, isWildcard = true), pt)
574574
}

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)