Skip to content

Disallow @_lifetime(borrow) for trivial 'inout' arguments #82189

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 3 commits into from
Jun 12, 2025

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Jun 11, 2025

  • [NFC] LifetimeDependence: fix indentation
    To avoid diff/merge confusion.

  • Disallow @_lifetime(borrow) for trivial 'inout' arguments
    @_lifetime(borrow holder) // ERROR
    func test(holder: inout Holder) -> NE

    Fixes rdar://153040843 ([nonescapable] disallow @_lifetime(borrow)
    for trivial 'inout' arguments)

atrick added 2 commits June 11, 2025 10:37
To avoid diff/merge confusion.
    @_lifetime(borrow holder) // ERROR
    func test(holder: inout Holder) -> NE

Fixes rdar://153040843 ([nonescapable] disallow @_lifetime(borrow)
for trivial 'inout' arguments)
@atrick atrick requested a review from meg-gupta June 11, 2025 18:35
@atrick
Copy link
Contributor Author

atrick commented Jun 11, 2025

@swift-ci test

@atrick
Copy link
Contributor Author

atrick commented Jun 11, 2025

@swift-ci test

// An owned/consumed BitwiseCopyable value can be effectively borrowed
// because its lifetime can be indefinitely extended.
if (loweredOwnership == ValueOwnership::Owned
&& isBitwiseCopyable(type, ctx)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't the same rule apply for @_lifetime(&) ? In which case we will need a similar check when kind == ParsedLifetimeDependenceKind::Inout

Copy link
Contributor

Choose a reason for hiding this comment

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

struct C {}

struct NE : ~Escapable {
  @_lifetime(immortal)
  init() {}
}

@_lifetime(&c)
func foo(_ c: consuming C) -> NE {
  NE()
}

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 don't think this should be legal:

@_lifetime(&c)
func foo(_ c: consuming C) -> NE {

We have a special case for BitwiseCopyable because they are frequently used in initializers where the ownership defaults to consuming but the only legal way to express the dependency is

@_lifetime(borrow c)

Copy link
Contributor

Choose a reason for hiding this comment

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

okay, makes sense!

@meg-gupta
Copy link
Contributor

I left a minor comment on inout lifetime dependencies. These changes itself lgtm.

@atrick atrick merged commit d90903a into swiftlang:main Jun 12, 2025
5 checks passed
@atrick atrick deleted the lifedep-trivial-inout branch June 12, 2025 17:31
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.

2 participants