-
Notifications
You must be signed in to change notification settings - Fork 1.1k
SIP-56-extended: Refined provablyDisjoint test. #18416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
62dda65
Update the perspective community build project to the latest upstream.
sjrd 9f5aa6f
Update `perspective` to be compatible with the current state of `main`.
sjrd a377544
Introduce MatchTypeCaseSpec to categorize match type cases.
sjrd c61674b
Use new specced match types for class type constructors.
sjrd 223be76
Use new specced match types for `scala.compiletime.int.S[n]`.
sjrd 3f17d5a
Short-circuit match type cases with missing captures in their patterns.
sjrd 628e50f
Use the specced match types for abstract tycons in patterns.
sjrd 9c19ada
Make sure in CI that we do not unexpectedly fall back on legacy match…
sjrd 048951c
Handle type member extractors as specced match types.
sjrd ccf7416
Introduce the SourceVersions 3.4 and 3.4-migration; make 3.4 the defa…
sjrd ff710e4
Disable legacy match types under source version >= 3.4.
sjrd bff2de6
Allow to reduce type member extractors when the member is a class.
sjrd aea28b9
Simplify the type member extractor logic.
sjrd 12e74ac
SIP-56-extended: Simpler provablyDisjoint test.
sjrd a84fbb1
Use a `pending` set to detect infinite recursion.
sjrd 4086ada
Remove disjointness of invariant type params based on isSameType.
sjrd f876971
Be more specific about higher-kinded types in provablyDisjoint.
sjrd cb94367
Do not use provablyEmpty anymore; use S <: T + provablyDisjoint(S, T)…
sjrd 980c9e7
Add regression tests for old issues fixed with the new match types.
sjrd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
370 changes: 245 additions & 125 deletions
370
compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
object Opaque { | ||
opaque type FieldType[K, +V] <: V = V | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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[_]] | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* Tests that the following property holds for a chosen set of types (S, T, U): | ||
* | ||
* If S <: T and T provably disjoint from U, then S provably disjoint from U. | ||
*/ | ||
|
||
class Parent[T] | ||
class Child[T] extends Parent[T] | ||
trait ChildTrait[T] extends Parent[T] | ||
|
||
class OtherClass | ||
|
||
trait Common[A] | ||
trait Left[A] extends Common[A] | ||
trait Right[A] extends Common[A] | ||
|
||
// Since Parent[Boolean] disjoint from Parent[Int], we must have Child[Boolean] also disjoint from Parent[Int] | ||
object Test1: | ||
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[Child[Int]] =:= Int] | ||
summon[MT[Child[Boolean]] =:= Boolean] | ||
end test | ||
end Test1 | ||
|
||
// Since Parent[Int] disjoint from OtherClass, we must have Child[Int] and ChildTrait[T] also disjoint from OtherClass | ||
object Test2: | ||
type MT[X] = X match | ||
case OtherClass => Int | ||
case Parent[Int] => Boolean | ||
|
||
def test(): Unit = | ||
summon[MT[OtherClass] =:= Int] | ||
summon[MT[Parent[Int]] =:= Boolean] | ||
|
||
summon[MT[Child[Int]] =:= Boolean] | ||
summon[MT[ChildTrait[Int]] =:= Boolean] | ||
end test | ||
end Test2 | ||
|
||
// Since Common[Int] is disjoint from Right[Boolean], we must have Left[Int] disjoint from Right[Boolean] | ||
object Test3: | ||
type MT[X] = X match | ||
case Right[Boolean] => Int | ||
case Any => Boolean | ||
|
||
def test(): Unit = | ||
summon[MT[Common[Int]] =:= Boolean] | ||
summon[MT[Left[Int]] =:= Boolean] | ||
end test | ||
end Test3 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've observed that a lot of people want to use this kind of pattern for type level records, what is the solution?
use class not opaque type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you have to use classes. In fact this test was very obviously wrong.
FieldType["A", Int]
is clearly not disjoint fromFieldType["B", Int]
since they both map toInt
! The fact that it passed before was definitely a bug, not a feature.