Skip to content

Fix #196. Errorneus tail-optimization of inner DefDef's #197

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 1 commit into from
Oct 26, 2014

Conversation

DarkDimius
Copy link
Contributor

Unless a DefDef is a result of desugaring an exception handler it shouldn't be optimized by tailrec.

There's a potential improvement here: to detect that a DefDef
is a label def which itself is called only in tail position.

This is a requirement to implement #194

Unless a DefDef is a result of desugaring an exception handler it shouldn't be optimized by tailrec.

There's a potential improvement here: to detect that a DefDef
 is a label def which itself is called only in tail position.

 This is a requirement to implement scala#194
@DarkDimius
Copy link
Contributor Author

@odersky please review. Also see comment in #196

@retronym
Copy link
Member

Perhaps I'm misunderstanding this, but why would nested functions be ineligible for tail call optimization?

scala> class Tail { def foo = { def bar(x: Int): Int = if (x == 0) 0 else bar(x - 1); bar(10) } }
defined class Tail

scala> :javap -v -p Tail#bar$1
  private final int bar$1(int);
    descriptor: (I)I
    flags: ACC_PRIVATE, ACC_FINAL
    Code:
      stack=2, locals=2, args_size=2
         0: iload_1
         1: iconst_0
         2: if_icmpne     7
         5: iconst_0
         6: ireturn
         7: iload_1
         8: iconst_1
         9: isub
        10: istore_1
        11: goto          0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      14     0  this   LTail;
            0      14     1     x   I
      LineNumberTable:
        line 7: 0
      StackMapTable: number_of_entries = 2
        frame_type = 0 /* same */
        frame_type = 6 /* same */

@DarkDimius
Copy link
Contributor Author

They are eligible themselves and in example that you are presenting, even after this commit the bar will be optimized. But the calls to outer function shouldn't be treated as available to tail call optimization, and this is the bug that this commit fixes.

eg for such code:

def foo: Int = {
  def bar = foo
  bar
  foo
}

The call to foo inside bar shouldn't get replaced with a call to a LabelDef.

@retronym
Copy link
Member

Thanks for the clarification. Perhaps a test case is warranted, or a reference to an existing test that now will pass as a result of this.

@odersky
Copy link
Contributor

odersky commented Oct 26, 2014

LGTM

DarkDimius added a commit that referenced this pull request Oct 26, 2014
Fix #196. Errorneus tail-optimization of inner DefDef's
@DarkDimius DarkDimius merged commit e992cf9 into scala:master Oct 26, 2014
@allanrenucci allanrenucci deleted the fix/tailrec-defdef branch December 14, 2017 19:23
WojciechMazur pushed a commit to WojciechMazur/dotty that referenced this pull request May 8, 2025
Backport "Only check logicalOwners for methods, and not for classes, when looking for proxies" to 3.3 LTS
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.

3 participants