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

[SR-14148] Language support for extending the lifetime of 'self' and local variables #56527

Open
atrick opened this issue Feb 3, 2021 · 1 comment
Labels
compiler The Swift compiler in itself feature A feature request or implementation

Comments

@atrick
Copy link
Member

atrick commented Feb 3, 2021

Previous ID SR-14148
Radar rdar://73793806
Original Reporter @atrick
Type New Feature
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels New Feature, LanguageFeatureRequest
Assignee None
Priority Medium

md5: 466cc712adde187236a5968500218f90

Issue Description:

We need to communicate to Swift developers how to manage the lifetime of their objects, particularly when handing off weak references.

In a recent Swift 5.4 change, the compiler now destroys objects immediately after their last use instead of keeping them alive until the end of the syntactic scope. In fact, the Swift compiler has always done this in certain cases; it is now doing it much more consistently. In the long run, this consistency actually shields programmers from unexpected behavior. It is also the basis for much more powerful ARC optimization being developed.

The change is only observable in code making invalid assumptions about when weak references are set to nil or when deinitializers run. The fix will generally involve reconsidering your use of `weak` or `unretained` or using `withExtendedLifetime` to explicitly mark the expected lifetime of an object.

There should be some easy-to-understand fairly unobtrusive way to extend the lifetime of a local variable, argument, or 'self' to the end of the lexical scope.

The current best practice for this is:

`defer { withExtendedLifetime(self) {} }`

That looks like quite a hack.

I'm using this radar to gather ideas for alternatives.

For example, we could add a @Keepalive annotation on variable declarations and a @Keepalive on methods that applies to 'self'.

{
  @keepalive let x = X()
  container.weakProperty = x
  container.doStuff()
  // x can't be released until the end of scope
}
@atrick
Copy link
Member Author

atrick commented Apr 14, 2021

I think there are two good options

1. Add a default empty closure to withExtendedLifetime for the more common usage:

defer { withExtendedLifetime(local) }

2. Add a variable attribute @_preciseLifetime with the same semantics as objc_precise_lifetime

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself feature A feature request or implementation
Projects
None yet
Development

No branches or pull requests

2 participants