-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Change case class desugaring and decouple Products and name-based-pattern-matching #1938
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
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0378330
Add {before,after}-pickling.txt to gitignore
OlivierBlanvillain 0ad5956
Workaround #1932 (bug trigged by desugaring changes)
OlivierBlanvillain c0ff8ad
Generate synthetic productElement/productArity methods above 22
OlivierBlanvillain 944e677
Decouple Product and pattern-matching
OlivierBlanvillain 5bf9d2b
Add tests
OlivierBlanvillain 198b5ce
Move isProductSubType to Applications & rename to canProductMatch
OlivierBlanvillain 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
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 |
---|---|---|
|
@@ -55,3 +55,5 @@ testlogs/ | |
local/ | ||
compiler/test/debug/Gen.jar | ||
|
||
compiler/before-pickling.txt | ||
compiler/after-pickling.txt |
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
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
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 |
---|---|---|
|
@@ -48,12 +48,12 @@ object Applications { | |
} | ||
|
||
/** Does `tp` fit the "product match" conditions as an unapply result type | ||
* for a pattern with `numArgs` subpatterns> | ||
* This is the case of `tp` is a subtype of the Product<numArgs> class. | ||
* for a pattern with `numArgs` subpatterns? | ||
* This is the case of `tp` has members `_1` to `_N` where `N == numArgs`. | ||
*/ | ||
def isProductMatch(tp: Type, numArgs: Int)(implicit ctx: Context) = | ||
0 <= numArgs && numArgs <= Definitions.MaxTupleArity && | ||
tp.derivesFrom(defn.ProductNType(numArgs).typeSymbol) | ||
numArgs > 0 && defn.isProductSubType(tp) && | ||
productSelectorTypes(tp).size == numArgs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
|
||
/** Does `tp` fit the "get match" conditions as an unapply result type? | ||
* This is the case of `tp` has a `get` member as well as a | ||
|
@@ -68,6 +68,9 @@ object Applications { | |
sels.takeWhile(_.exists).toList | ||
} | ||
|
||
def productArity(tp: Type)(implicit ctx: Context) = | ||
if (defn.isProductSubType(tp)) productSelectorTypes(tp).size else -1 | ||
|
||
def productSelectors(tp: Type)(implicit ctx: Context): List[Symbol] = { | ||
val sels = for (n <- Iterator.from(0)) yield tp.member(nme.selectorName(n)).symbol | ||
sels.takeWhile(_.exists).toList | ||
|
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
File renamed without changes.
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,45 @@ | ||
case class Large( | ||
e1: Int, | ||
e2: Int, | ||
e3: Int, | ||
e4: Int, | ||
e5: Int, | ||
e6: Int, | ||
e7: Int, | ||
e8: Int, | ||
e9: Int, | ||
e10: Int, | ||
e11: Int, | ||
e12: Int, | ||
e13: Int, | ||
e14: Int, | ||
e15: Int, | ||
e16: Int, | ||
e17: Int, | ||
e18: Int, | ||
e19: Int, | ||
e20: Int, | ||
e21: Int, | ||
e22: Int, | ||
e23: Int | ||
) | ||
|
||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
val l = Large(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23) | ||
|
||
assert(l.productArity == 23) | ||
|
||
assert(l.productElement(0) == 1) | ||
assert(l.productElement(1) == 2) | ||
assert(l.productElement(21) == 22) | ||
assert(l.productElement(22) == 23) | ||
|
||
try { | ||
l.productElement(23) | ||
??? | ||
} catch { | ||
case e: IndexOutOfBoundsException => assert(e.getMessage == "23") | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
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,40 @@ | ||
case class C1(i: String, s: Int) { def isEmpty = false; def get = ("EMPTY", -1) } | ||
case class C2(i: String, s: String) { def isEmpty = false; def get = (-1, -2, -3) } | ||
|
||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
// When both Product and name based patterns with same arity are available, | ||
// we follow scalac and silently use the Product one: | ||
|
||
val c1 = C1("s", 0) | ||
c1 match { | ||
case C1(a, b) => | ||
assert(a == "s") | ||
assert(b == 0) | ||
} | ||
|
||
// When the size differ, both are patterns become usable: | ||
|
||
val c2 = C2("a", "b") | ||
c2 match { | ||
case C2(a, b) => | ||
assert(a == "a") | ||
assert(b == "b") | ||
} | ||
|
||
c2 match { | ||
case C2(a, b, c) => | ||
assert(a == -1) | ||
assert(b == -2) | ||
assert(c == -3) | ||
} | ||
|
||
// Interestingly things also compile with a single pattern, in which case | ||
// the tuple returned by get is binded to `a`: | ||
|
||
c2 match { | ||
case C2(a) => | ||
assert(a == (-1, -2, -3)) | ||
} | ||
} | ||
} |
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,26 @@ | ||
case class Foo() | ||
|
||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
assert(Foo.unapply(Foo()) == true) | ||
|
||
// unapply generate by scalac are `_ != null`, | ||
// dotty returns true in all cases | ||
assert(Foo.unapply(null) == true) | ||
|
||
Foo() match { | ||
case Foo() => () | ||
case _ => ??? | ||
} | ||
|
||
Foo() match { | ||
case _: Foo => () | ||
case _ => ??? | ||
} | ||
|
||
(Foo(): Any) match { | ||
case Foo() => () | ||
case _ => ??? | ||
} | ||
} | ||
} |
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.
The
isProductSubType
method should be renamed and moved toApplications
.