Skip to content

Commit

Permalink
SIP-56-extended: Simpler provablyDisjoint test.
Browse files Browse the repository at this point in the history
  • Loading branch information
sjrd committed Aug 17, 2023
1 parent aea28b9 commit 1a8575e
Show file tree
Hide file tree
Showing 15 changed files with 418 additions and 141 deletions.
358 changes: 238 additions & 120 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions tests/neg/6314-1.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
object G {
final class X
final class Y
trait X
class Y
class Z

trait FooSig {
type Type
Expand All @@ -13,14 +14,14 @@ object G {
type Foo = Foo.Type

type Bar[A] = A match {
case X & Y => String
case X & Z => String
case Y => Int
}

def main(args: Array[String]): Unit = {
val a: Bar[X & Y] = "hello" // error
val i: Bar[Y & Foo] = Foo.apply[Bar](a)
val b: Int = i // error
val b: Int = i
println(b + 1)
}
}
16 changes: 16 additions & 0 deletions tests/neg/6314-6.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- Error: tests/neg/6314-6.scala:26:3 ----------------------------------------------------------------------------------
26 | (new YY {}).boom // error: object creation impossible
| ^
|object creation impossible, since def apply(fa: String): Int in trait XX in object Test3 is not defined
|(Note that
| parameter String in def apply(fa: String): Int in trait XX in object Test3 does not match
| parameter Test3.Bar[X & Object with Test3.YY {...}#Foo] in def apply(fa: Test3.Bar[X & YY.this.Foo]): Test3.Bar[Y & YY.this.Foo] in trait YY in object Test3
| )
-- Error: tests/neg/6314-6.scala:52:3 ----------------------------------------------------------------------------------
52 | (new YY {}).boom // error: object creation impossible
| ^
|object creation impossible, since def apply(fa: String): Int in trait XX in object Test4 is not defined
|(Note that
| parameter String in def apply(fa: String): Int in trait XX in object Test4 does not match
| parameter Test4.Bar[X & Object with Test4.YY {...}#FooAlias] in def apply(fa: Test4.Bar[X & YY.this.FooAlias]): Test4.Bar[Y & YY.this.FooAlias] in trait YY in object Test4
| )
12 changes: 4 additions & 8 deletions tests/neg/6314-6.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ object Test3 {
trait YY extends XX {
type Foo = X & Y

def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa // error
// overriding method apply in trait XX of type (fa: String): Int;
// method apply of type (fa: String): String has incompatible type
def apply(fa: Bar[X & Foo]): Bar[Y & Foo] = fa
}
(new YY {}).boom
(new YY {}).boom // error: object creation impossible
}

object Test4 {
Expand All @@ -49,9 +47,7 @@ object Test4 {
trait YY extends XX {
type Foo = X & Y

def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa // error
// overriding method apply in trait XX of type (fa: String): Int;
// method apply of type (fa: String): String has incompatible type
def apply(fa: Bar[X & FooAlias]): Bar[Y & FooAlias] = fa
}
(new YY {}).boom
(new YY {}).boom // error: object creation impossible
}
44 changes: 44 additions & 0 deletions tests/neg/6314.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
-- [E007] Type Mismatch Error: tests/neg/6314.scala:28:27 --------------------------------------------------------------
28 | val i: Bar[Y | Type] = 1 // error
| ^
| Found: (1 : Int)
| Required: Test1Bis.Bar[Test1Bis.Y | Test.this.Type]
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Test1Bis.Bar[Test1Bis.Y | Test.this.Type]
| failed since selector Test1Bis.Y | Test.this.Type
| does not match case Test1Bis.X & Test1Bis.Y => String
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case Any => Int
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg/6314.scala:45:33 --------------------------------------------------------------
45 | def right(fa: Bar[L]): Int = fa // error
| ^^
| Found: (fa : Wizzle.this.Bar[L])
| Required: Int
|
| where: L is a type in trait Wizzle with bounds <: Int & Singleton
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg/6314.scala:55:33 --------------------------------------------------------------
55 | def right(fa: Bar[L]): Int = fa // error
| ^^
| Found: (fa : Wazzlo.this.Bar[L])
| Required: Int
|
| where: L is a type in trait Wazzlo with bounds <: Int & AnyVal
|
| longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: tests/neg/6314.scala:65:33 --------------------------------------------------------------
65 | def right(fa: Bar[L]): Int = fa // error
| ^^
| Found: (fa : Wuzzlu.this.Bar[L])
| Required: Int
|
| where: L is a type in trait Wuzzlu with bounds <: String & AnyRef
|
| longer explanation available when compiling with `-explain`
31 changes: 25 additions & 6 deletions tests/neg/6314.scala
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
final class X
final class Y

object Test1 {
// X, Y and Z are unrelated, Y is provably disjoint from Z, but X is not provably disjoint with either
trait X
class Y
class Z

trait Test {
type Type
// This is testing that both permutations of the types in a &
// are taken into account by the intersection test
val i: Bar[Y & Type] = 1 // error
// are taken into account by the provablyDisjoint test
val i: Bar[Y & Type] = 1 // ok, disjoint from X & Z because Y and Z are disjoint
}

type Bar[A] = A match {
case X & Y => String
case X & Z => String
case Y => Int
}
}

object Test1Bis {
final class X
final class Y

trait Test {
type Type
// This is testing that both permutations of the types in a |
// are taken into account by the provablyDisjoint test
val i: Bar[Y | Type] = 1 // error
}

type Bar[A] = A match {
case X & Y => String
case Any => Int
}
}

object Test2 {
trait Wizzle[L <: Int with Singleton] {
type Bar[A] = A match {
Expand Down
15 changes: 15 additions & 0 deletions tests/neg/i13190.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

-- [E172] Type Error: tests/neg/i13190/B_2.scala:14:38 -----------------------------------------------------------------
14 | summon[FindField[R, "B"] =:= Double] // error
| ^
| Cannot prove that Test.FindField[Test.R, ("B" : String)] =:= Double.
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Test.FindField[Test.R, ("B" : String)]
| failed since selector Test.R
| does not match case Opaque.FieldType[("B" : String), f] *: t => f
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case _ *: t => Test.FindField[t, ("B" : String)]
2 changes: 1 addition & 1 deletion tests/pos/i13190/A_1.scala → tests/neg/i13190/A_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
object Opaque {
opaque type FieldType[K, +V] <: V = V
}
}
2 changes: 1 addition & 1 deletion tests/pos/i13190/B_2.scala → tests/neg/i13190/B_2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ object Test {
//val f2: Int = f

type R = FieldType["A", Int] *: FieldType["B", Double] *: FieldType["C", String] *: FieldType["D", Boolean] *: EmptyTuple
summon[FindField[R, "B"] =:= Double]
summon[FindField[R, "B"] =:= Double] // error
}
14 changes: 14 additions & 0 deletions tests/neg/i13190b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- [E172] Type Error: tests/neg/i13190b.scala:18:38 --------------------------------------------------------------------
18 | summon[FindField[R, "B"] =:= Double] // error
| ^
| Cannot prove that Test.FindField[Test.R, ("B" : String)] =:= Double.
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Test.FindField[Test.R, ("B" : String)]
| failed since selector Test.R
| does not match case Opaque.FieldType[("B" : String), f] *: t => f
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case _ *: t => Test.FindField[t, ("B" : String)]
19 changes: 19 additions & 0 deletions tests/neg/i13190b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
object Opaque {
opaque type FieldType[K, +V] <: V = V
}

import Opaque.*

object Test {
type FindField[R <: scala.Tuple, K] = R match {
case FieldType[K, f] *: t => f
case _ *: t => FindField[t, K]
}

val f: FieldType["A", Int] = ???
val f1: Int = f
//val f2: Int = f

type R = FieldType["A", Int] *: FieldType["B", Double] *: FieldType["C", String] *: FieldType["D", Boolean] *: EmptyTuple
summon[FindField[R, "B"] =:= Double] // error
}
17 changes: 17 additions & 0 deletions tests/neg/i15312.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- [E007] Type Mismatch Error: tests/neg/i15312.scala:7:27 -------------------------------------------------------------
7 |val b: F[{type A = Int}] = "asd" // error
| ^^^^^
| Found: ("asd" : String)
| Required: F[Object{type A = Int}]
|
| Note: a match type could not be fully reduced:
|
| trying to reduce F[Object{type A = Int}]
| failed since selector Object{type A = Int}
| does not match case Object{type A = Float} => Int
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case Object{type A = Int} => String
|
| longer explanation available when compiling with `-explain`
2 changes: 1 addition & 1 deletion tests/pos/i15312.scala → tests/neg/i15312.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ type F[t] =
case {type A = Int} => String

val a: F[{type A = Float}] = 10
val b: F[{type A = Int}] = "asd" // Found:("asd" : String) Required: F[Object{A = Int}]
val b: F[{type A = Int}] = "asd" // error
2 changes: 2 additions & 0 deletions tests/pos/i15677.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// scalac: -Yno-deep-subtypes:false

class Inv[A]

class Foo[B, M[_]]
Expand Down
16 changes: 16 additions & 0 deletions tests/pos/mytest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Parent[T](val x: T)

class Child[T](x: T) extends Parent(x)

type MT[X] = X match
case Parent[Int] => Int
case Parent[Boolean] => Boolean

def test(): Unit =
summon[MT[Parent[Int]] =:= Int]
summon[MT[Parent[Boolean]] =:= Boolean]
//summon[MT[Parent[Any]] =:= Int]

summon[MT[Child[Int]] =:= Int]
summon[MT[Child[Boolean]] =:= Boolean]
end test

0 comments on commit 1a8575e

Please sign in to comment.