Skip to content

Fix #3853 and #4151: Compile code in the macro definition and remove interpreter #4155

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 5 commits into from
Mar 29, 2018

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented Mar 22, 2018

The only interpreted code remaining is a call to a static method
containing a lambda which can compute the resulting inlined quoted
expression. Arguments to the macro are trivially computed from the
inlined call and bindings.

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

performance test scheduled: 1 job(s) in queue, 0 running.

@dottybot
Copy link
Member

performance test failed:

Error line number: 24

[check /data/workspace/bench/logs/pull-4155-03-22-15.36.out for more information]

@nicolasstucki nicolasstucki changed the title Remove interpretation of inlined quotes Compile code in the macro definition and remove interpreter Mar 23, 2018
@nicolasstucki nicolasstucki force-pushed the kill-interpreter branch 3 times, most recently from 06ade09 to 5e0b55a Compare March 23, 2018 14:29
@nicolasstucki nicolasstucki changed the title Compile code in the macro definition and remove interpreter Fix #3853 and #4151: Compile code in the macro definition and remove interpreter Mar 23, 2018
@nicolasstucki
Copy link
Contributor Author

@liufengyun do you know what failed in the benchmark server?

@liufengyun
Copy link
Contributor

liufengyun commented Mar 23, 2018 via email

@liufengyun
Copy link
Contributor

Cause diagnosed: in #4149 , an empty file Foo.scala is incorrectly added to the repo.

That error should not cause the benchmarks to fail, but the following find command failed due to the existence of Foo.scala in current directory. If I remove Foo.scala, everything works correctly.

find /data/workspace/bench/tests/scala-library -name *.scala

@nicolasstucki
Copy link
Contributor Author

@liufengyun thanks :)

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

performance test scheduled: 1 job(s) in queue, 0 running.

@dottybot
Copy link
Member

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4155/ to see the changes.

Benchmarks is based on merging with master (c89f8fa)

@Blaisorblade
Copy link
Contributor

That error should not cause the benchmarks to fail, but the following find command failed due to the existence of Foo.scala in current directory. If I remove Foo.scala, everything works correctly.

find /data/workspace/bench/tests/scala-library -name *.scala

As a rule, it seems good to prevent such issues by adding quotes around *.scala, hence writing find /data/workspace/bench/tests/scala-library -name "*.scala".

…preter

The only interpreted code remaining is a call to a static method
containing a lambda which can compute the resulting inlined quoted
expression. Arguments to the macro are trivially computed from the
inlined call and bindings.
@scala scala deleted a comment from dottybot Mar 26, 2018
@scala scala deleted a comment from dottybot Mar 26, 2018
@nicolasstucki nicolasstucki requested a review from odersky March 26, 2018 06:49
@biboudis biboudis self-requested a review March 26, 2018 11:28
Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a pity that we do not allow general interpretation in an inline macro. Why do we have to remove that possibility?

@@ -231,7 +231,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
// be duplicated
// 2. To enable correct pickling (calls can share symbols with the inlined code, which
// would trigger an assertion when pickling).
val callTrace = Ident(call.symbol.topLevelClass.typeRef).withPos(call.pos)
val callTrace =
if (call.symbol.is(Macro)) call
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why make the exception for macros? Since there is a reasoning in the comment above why we rewrite calls to callTraces, we need to add to the comment a reasoning why the same does not apply to macro calls.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the comment and making this optimization at ReifyQuotes when the call is processed.

@odersky odersky assigned nicolasstucki and unassigned odersky Mar 26, 2018
@nicolasstucki
Copy link
Contributor Author

Removing the interpreter does not really limit what we could already write in terms of macros. @odersky do you have some precise examples where we would need interpretation?

This transformation can also be extended to support multiple spliced in a single macro by making the macro return a list of lambdas. We would only need to find the additional definitions in the body of the inline method (such as y) and also pass them to the lambdas.

def foo(inline x: Int): Int = {
  val y  = 3
  ~impl2(x) + ~impl3('(y))
}

This could also be performed by the interpreter, but is currently not supported as well.

One thing is not possible anymore with the changes in this PR. We cannot write inline macros as extension methods in implicit classes. Those were only working by an abuse of the inline bindings which were wrongly moved to be interpreted to allow this to work. The failed if the implicit class was instantiated explicitly. The correct way to would be using the new extension methods, where we might additionally need to require the this parameter to be an inline parameter of the resulting method (this would need a direct encoding of the extensions without value classes).

Apply the simplification later in ReifyQuotes when
call has been processed.
This was performed to allow some inlined `this` bindings
to be evaluated. It was not always possible and hence inconsistent.
Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I get it now after @nicolasstucki explained it to me. LGTM.

@nicolasstucki nicolasstucki merged commit 1183d0d into scala:master Mar 29, 2018
@Blaisorblade Blaisorblade deleted the kill-interpreter branch April 5, 2018 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants