-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #5386: Generate a synthetic val def and then apply the unary operator #5387
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
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.
Open question: Should this happen earlier? What if I want to inspect the type of this block in a macro?
compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
Outdated
Show resolved
Hide resolved
compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
Outdated
Show resolved
Hide resolved
compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
Outdated
Show resolved
Hide resolved
compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
Outdated
Show resolved
Hide resolved
@allanrenucci good question. What would be a recommended compiler phase? |
I don't know that's why I am raising the question. Hopefully someone more knowledgeable will see the question 😄 |
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 implementation LGTM. Not sure if there is a better place for it.
All suggestions where incorporated.
@@ -22,6 +23,7 @@ object InterceptedMethods { | |||
* - `x.##` for ## in Any becomes calls to ScalaRunTime.hash, | |||
* using the most precise overload available | |||
* - `x.getClass` for getClass in primitives becomes `x.getClass` with getClass in class Object. | |||
* - `!{...;true}` becomes val tmp = {...;true};!tmp (similar to other primitives/unary ops) |
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.
What other primitives ? Where is that defined ?
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 should have written literal constants instead of primitives.
@@ -45,6 +47,16 @@ class InterceptedMethods extends MiniPhase { | |||
ctx.log(s"$phaseName rewrote $tree to $rewritten") | |||
rewritten | |||
} | |||
// if the qualifier is constant folded then its type doesn't have a symbol |
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.
but if its type doesn't have a symbol, does that always mean that the qualifier is constant-folded ?
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 qualifier is not constant folded due to the side effectful println
.
@@ -45,6 +47,16 @@ class InterceptedMethods extends MiniPhase { | |||
ctx.log(s"$phaseName rewrote $tree to $rewritten") | |||
rewritten | |||
} | |||
// if the qualifier is constant folded then its type doesn't have a symbol | |||
// in case a unary operator is applied to a block (potentially containing impure expressions) | |||
// we create a synthetic variable and then apply the operator |
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.
What is special about unary operators here compared to any other method call on a block ?
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.
Would you mean something like that?
{
println("!")
1
}+2
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.
It feels like this should have a more general solution, independent of the fact that these are operators. I.e. in general:
{ ... }.m where m has constant type v --> { ...; v }
We should constant fold those cases
See #5479 for an another fix. |
Solved by #5479. |
I added the logic that lifts a block with a side-effectful operation at the
InterceptedMethods
phase. Is this the most appropriate place for that?What happens is essentially:
is rewritten to ->