-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Optimize tailcalls even when called with different type arguments. #6065
Conversation
The check might have been there because it badly interacts with specialization. |
Indeed, thank you. I will add a check that differing type arguments must not be specialized. |
@DarkDimius : Do you know why this restriction exist? Dotty seems to have a similar one (test/files/pos/t9647.scala from this PR does not compile in Dotty because of https://github.com/lampepfl/dotty/blob/851c3c2212b7457dedc9ad1e59ff688b17458db5/compiler/src/dotty/tools/dotc/transform/TailRec.scala#L275) |
4194290
to
cc82947
Compare
I added a check that |
Why do we only do this in case the method is
and that
Moreover, there are plenty of places on the Internet which claim that tail-call optimization is automatic. I can't think of a reason why I'd want to write a tail-recursive method, and have it not be optimized because I forgot the |
@hrhino I guess I just wanted to keep the change conservative. |
When I enable it wholesale, this test fails. The method invocation it is looking for is optimized away. How should I update that test so that it still checks for scala/bug#8062? |
Thanks for doing this! I have wanted to take a stab at this. I hope we can make it enabled by default. |
cc82947
to
839ed69
Compare
I checked with Scala 2.10.3 that scala/bug#8062 is reproducible even with the recursive call in non-tail position. I updated the test accordingly so that it doesn't interact with this PR. (Aside: where does |
The restriction to only elim tail calls when type args are forwarded came in a4e5d4a, one day after the genesis of the tailcalls phase. This predated the specialization phase by four years. @dragos do you recall if the restriction was due to astounding prescience about future interactions with specialization? Or maybe just caution?
Thanks for checking before modifying the test. Adding
https://github.com/retronym/libscala The scripts are somewhat out of date because of changes to the format and repository of our per-commit builds. I've got new versions in https://gist.github.com/retronym/6b5cea4d94d51fbcf5d7a0587404492e |
Thanks, @retronym. I saw it used in issue descriptions and didn't know where it came from. |
839ed69
to
418773e
Compare
Not him, but my guess would be that at some point we also compiled to a platform that didn't erase types :-) (MSIL) |
Looks like related to scala/bug#10493 |
Maybe we should push this phase back until after lambdalift? That would fix both bugs (different polymorphic instantiations of both the method and the receiver), since we're looking at erased (and specialized) types. |
Just changing
|
That's pretty good :-) Thanks for trying it out! |
We can start with this PR and take that investigation as a separate one for 2.13.0-M4 |
Good stuff @TomasMikula! |
🎉 |
This PR turns off the check that the recursive tail-call is made with the same type arguments, if the tailcall optimization is requested explicitly via
@tailrec
.This allows to tail-optimize, for example, operations on type-aligned sequences.
I believe the check was there for a reason. However, the tests pass and I can't think of a case where it would be unsafe. Please let me know if I'm wrong.