Skip to content
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

Make more anonymous functions static #19251

Merged
merged 3 commits into from
Dec 14, 2023
Merged

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Dec 12, 2023

An anonymous function in a static object was previously mapped to a member of that object. We now map it to a static member of the toplevel class instead. This causes the backend to memoize the function, which fixes #19224. On the other hand, we don't do that for anonymous functions nested in the object constructor, since that can cause deadlocks (see run/deadlock.scala).

Scala 2's behavior is different: it does lift lambdas in constructors to be static, too, which can cause deadlocks.

Fixes #19224

@SethTisue
Copy link
Member

SethTisue commented Dec 12, 2023

commit messages have wrong ticket number (should be 19224, not 19924 — I fixed it in PR description)

@retronym
Copy link
Member

I've added some comments in #19224 (comment)

}

val t1 = new C
val t2 = new C

This comment was marked as resolved.

)
|| (
&& (!sym.isAnonymousFunction || sym.owner.ownersIterator.exists(_.isConstructor))
// For anonymous functions in static objects, we prefer them to be static because
Copy link
Member

Choose a reason for hiding this comment

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

What does the "in static objects" part mean here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Static means toplevel or nested in a static object.

This comment was marked as resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It added more comments. Hope it is clearer now.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, that helps me understand.

An anonymous function in a static object was previously mapped to a member
of that object. We now map it to a static member of the toplevel class instead.
This causes the backend to memoize the function, which fixes scala#19224. On the
other hand, we don't do that for anonymous functions nested in the object
constructor, since that can cause deadlocks (see run/deadlock.scala).

Scala 2's behavior is different: it does lift lambdas in constructors
to be static, too, which can cause deadlocks.

Fixes scala#19224
Copy link
Member

@retronym retronym left a comment

Choose a reason for hiding this comment

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

LGTM once the typo in the comment is fixed

def setLogicOwner(local: Symbol) =
val encClass = local.owner.enclosingClass
// When to [efer enclosing class over enclosing package:
Copy link
Member

Choose a reason for hiding this comment

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

Typo

)
|| (
&& (!sym.isAnonymousFunction || sym.owner.ownersIterator.exists(_.isConstructor))
// For anonymous functions in static objects, we prefer them to be static because
Copy link
Member

Choose a reason for hiding this comment

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

Thanks, that helps me understand.

@odersky odersky merged commit f8f2ae2 into scala:main Dec 14, 2023
19 checks passed
@odersky odersky deleted the fix-19224 branch December 14, 2023 08:47
@odersky odersky added the backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. label Dec 14, 2023
@odersky
Copy link
Contributor Author

odersky commented Dec 14, 2023

I believe it would be good to backport that patch to LTS, even though it changes runtime behavior.

@Kordyjan Kordyjan added this to the 3.4.0 milestone Dec 20, 2023
unkarjedy pushed a commit to JetBrains/intellij-scala that referenced this pull request May 16, 2024
…n stopping in lambdas

#SCL-22554 fixed
#SCL-22145

- Scala 3.4 and later tries to compile lambdas to the outermost static class.
- The reasons for this are explained in scala/scala3#19251.
- When trying to stop at breakpoints inside lambdas, it is important to load the outermost class and its nested classes.
- Java also does this in the platform implementation.
- Tests that cover code examples mentioned in the Scala 3 PR have been added.
unkarjedy pushed a commit to JetBrains/intellij-scala that referenced this pull request May 16, 2024
…n stopping in lambdas

#SCL-22554 fixed
#SCL-22145

- Scala 3.4 and later tries to compile lambdas to the outermost static class.
- The reasons for this are explained in scala/scala3#19251.
- When trying to stop at breakpoints inside lambdas, it is important to load the outermost class and its nested classes.
- Java also does this in the platform implementation.
- Tests that cover code examples mentioned in the Scala 3 PR have been added.
WojciechMazur added a commit that referenced this pull request Jun 26, 2024
Backports #19251 to the LTS branch.

PR submitted by the release tooling.
[skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it.
Projects
None yet
5 participants