-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #8530: Support inline unapply #8542
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
Conversation
d857d94
to
9c62e41
Compare
3f3a3da
to
c98e14c
Compare
I did not get yet the motivation and approach for this change.
|
When we want to implement it with a macro. In that case, one would recover some statically known information such as
With that information, we could either generate inlined unapplies that:
For example the
I do not understand this question. Is that related to the old
Yes, this change is orthogonal to #8543 and can be composed with retained inline unapply. |
No, I mean, why not just make the |
It is not related with the usecase of #8543. When we inline the unapply at the call site we need to place it in the tree. It is placed in the We cannot really place the expansion as it in the pattern because the patterns are unaware of the scrutinee. That happens knowledge is gained in x match
case <Some(x)>(y) => .... The first thing we need is to abstract over the scrutinee. A simple way to do it is with a lambda that receives the scrutinee. x match
case <(x:T) => Some(x)>(y) => .... This works, but we have to compose it with polymorphic and context function types to support But with this previous approach, the encoding for a call to If we wrap the expansion in a method instead (in a class), then the signature of this method will match the original. This allows x match
case <(new { def unapply(x: T) = Some(x) }).unapply>(y) => .... This implies that the Then
where
|
I still don't understand. The generated code looks much worse than either the non-inlined code, or an imagined inlined code. What I am missing: How does the inliner come into play here? I understand that the rhs of the |
Now I added a phase result of tests/run/i8530-b.scala after typer:
...
val myRegexp1: MyRegex[("foo" : String)] = new MyRegex["foo".type]()
"foo" match {
case
{
final class $anon() extends Object() {
def unapplySeq(s: CharSequence): Option[List[String]] = {
(if s.==("foo") then Some.apply[scala.collection.immutable.Nil.type](Nil)
else None):Option[List[String]]
}
}
new Object {...}()
}()
=>
()
}
...
result of tests/run/i8530-b.scala after MegaPhase{elimOpaque, tryCatchPatterns, patternMatcher, explicitOuter, explicitSelf, stringInterpolatorOpt, crossCast}:
...
val myRegexp1: MyRegex[("foo" : String)] = new MyRegex[("foo" : String)]()
matchResult1[Unit]:
{
case val x1: ("foo" : String) = "foo"
{
case val x2: Option[List[String]] =
{
final class $anon() extends Object() {
def unapplySeq(s: CharSequence): Option[List[String]] =
{
(if s.==("foo") then Some.apply[scala.collection.immutable.Nil.type](Nil)
else None):Option[List[String]]
}
}
new Object {...}()
}.unapplySeq(x1)
if x2.isEmpty.unary_! then
...
else ()
}
throw new MatchError(x1)
}
...
result of tests/run/i8530-b.scala after MegaPhase{pruneErasedDefs, inlinePatterns, vcInlineMethods, seqLiterals, intercepted, getters, elimByName, liftTry, collectNullableFields, elimOuterSelect, augmentScala2Traits, resolveSuper, functionXXLForwarders, paramForwarding, genericTuples, arrayConstructors}:
...
val myRegexp1: MyRegex[("foo" : String)] = new MyRegex[("foo" : String)]()
matchResult1[Unit]:
{
case val x1: ("foo" : String) = "foo"
{
case val x2: Option[List[String]] =
{
(if x1.==("foo") then Some.apply[scala.collection.immutable.Nil.type](Nil)
else None):Option[List[String]]
}
if x2.isEmpty.unary_! then
...
else ()
}
throw new MatchError(x1)
}
}
... |
85e75c7
to
caff137
Compare
53b287a
to
efc258d
Compare
@odersky, apart from taking care of the review comments I also made |
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.
Changes to beta reduction LGTM
Support the following kind of use case
where the call to
MyPattern.unapply
will get inline and possibly be a macro.The pattern is transformed into a new anonymous class that implements the same unapply. Then the inner call to
MyPattern.unnaply
is inlined.This anonymous class is optimized away in
inlinedPatterns
afterpatternMatcher
.It supports
unapply
s