Skip to content

LifetimeDependence: Support function types#86842

Merged
aidan-hall merged 8 commits into
swiftlang:mainfrom
aidan-hall:just-func-type-lifetimes-try-print
Feb 6, 2026
Merged

LifetimeDependence: Support function types#86842
aidan-hall merged 8 commits into
swiftlang:mainfrom
aidan-hall:just-func-type-lifetimes-try-print

Conversation

@aidan-hall
Copy link
Copy Markdown
Contributor

@aidan-hall aidan-hall commented Jan 28, 2026

First part of work originally from #85414.
Supersedes #86795.

The approach taken in this PR is as follows:

  1. Enable lifetime attribute parsing and lifetime inference for function types.
  2. When printing a Swift type, print a @_lifetime annotation using parameter labels when possible.
  3. If a target or source parameter does not have a label, fall back to printing indices. In swiftinterface files, do not print that lifetime, under the assumption that it was inferred.

@aidan-hall aidan-hall self-assigned this Jan 28, 2026
@slavapestov
Copy link
Copy Markdown
Contributor

Yeah, one of the fundamental invariants in the AST is that Types are supposed to be immutable, and uniqued. Let's not violate that for any reason.

Comment thread include/swift/AST/LifetimeDependence.h Outdated
@aidan-hall aidan-hall changed the title LifetimeDependence: Support function types without modifying LifetimeDependenceInfo LifetimeDependence: Support function types Jan 28, 2026
@aidan-hall aidan-hall marked this pull request as ready for review January 29, 2026 15:08
@QuietMisdreavus QuietMisdreavus removed their request for review January 29, 2026 15:26
@aidan-hall aidan-hall force-pushed the just-func-type-lifetimes-try-print branch 2 times, most recently from 23f51f0 to 2275893 Compare January 29, 2026 16:22
Comment thread lib/AST/FeatureSet.cpp
Comment thread include/swift/AST/TypeAttr.def Outdated
Comment thread lib/Sema/TypeCheckType.cpp Outdated
Comment thread include/swift/AST/TypeRepr.h Outdated
Comment thread include/swift/AST/TypeCheckRequests.h Outdated
@meg-gupta
Copy link
Copy Markdown
Contributor

meg-gupta commented Jan 29, 2026

Can you add some tests to cover SIL lifetime diagnostics and function types? test/SILOptimizer/lifetime_dependence/lifetime_dependence_borrow_fail.swift and test/SILOptimizer/lifetime_dependence/lifetime_dependence_copy_fail.swift have some examples with function declarations.

@aidan-hall aidan-hall force-pushed the just-func-type-lifetimes-try-print branch 2 times, most recently from ddbaa3e to e5729a3 Compare February 2, 2026 16:52
@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci test macos

@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci test linux

@aidan-hall aidan-hall force-pushed the just-func-type-lifetimes-try-print branch from 33121ed to 482c695 Compare February 5, 2026 12:46
@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci test

@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci smoke test

@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci please test source compatibility

This addresses feedback from swiftlang#86560:
- Remove redundant collectParameterInfo call
- Consistent naming of ParamInfo variables
- Explicit type name instead of decltype

Also add nullptr checks on afd, as appropriate.
@aidan-hall aidan-hall force-pushed the just-func-type-lifetimes-try-print branch 2 times, most recently from 142e117 to 7e903f8 Compare February 5, 2026 12:58
@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci test

@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci smoke test

@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci test source compatibility

…format

The isFromAnnotation flag is set if and only if the lifetime originates from a
@Lifetime or @_lifetime annotation in the source program.

isFromAnnotation==false means that the lifetime dependence checker would infer
the same lifetime if the Swift type or decl was printed without an annotation
for that dependency. More specifically, it means that the depenence was inferred
by the lifetime dependence checker.

Some dependencies on imported C/C++ decls are "inferred", but they either
correspond to explicit lifetime information in the source (smart pointers,
lifetimebound attribute) or are likely to differ from what the dependence
checker would infer. As such, we set the flag to true for all of them.
To a function type's lifetimes, a base version of the type is first created with
no lifetime dependence info. This is then passed to the dependence checker, and
the resulting dependencies are added to it.

It would be possible to do this analysis by passing just the parameter list and
result type (which are available before the type is created), but this approach
lets us avoid dealing with a header inclusion cycle between Types.h, ExtInfo.h,
and LifetimeDependence.h, since it does not require AnyFunctionType::Param to be
defined in LifetimeDependence.h.
We fall back to indices when labels are not available, but labels are
preferable, because they readable, stable, and preferred by the lifetime
dependencies proposal.
Includes:
- rdar://166912068 test case
- Nested type SIL tests
- rdar://160894371 test
- Many more
@aidan-hall aidan-hall force-pushed the just-func-type-lifetimes-try-print branch from 7e903f8 to 6aa5578 Compare February 5, 2026 14:50
@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci smoke test

@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci test

@aidan-hall
Copy link
Copy Markdown
Contributor Author

@swift-ci test source compatibility

Copy link
Copy Markdown
Contributor

@meg-gupta meg-gupta left a comment

Choose a reason for hiding this comment

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

LGTM!

@aidan-hall aidan-hall merged commit e98a7a6 into swiftlang:main Feb 6, 2026
7 checks passed
atrick added a commit to atrick/swift that referenced this pull request Feb 24, 2026
A nonescaping closure that returns a ~Escapable result and has no @_lifetime
annotation is assumed to depend on its closure context.

This fixes overly strict type checking introduced by:

    commit e98a7a6
    Date:   Fri Feb 6 02:09:25 2026
    Merge pull request swiftlang#86842
    LifetimeDependence: Support function types

Fix:

1. Disable missing dependency diagnostics for ~Escapable results

Continue allow the most basic nonescaping closure types without annotation:

    func f(body: () -> NE) -> NE

2. Disable single-parameter inference for function types

Do *not* infer a default parameter dependency here:

    func f(body: (AnyObject) -> NE) -> NE

The single-parameter rule should only apply to unambiguous function
declarations. It never applies to function types. Function types should instead
infer a dependency on the closure context.

Fixes rdar://171031632 ([nonescapable] allow nonescaping closures to return
non-Escapable types)
atrick added a commit to atrick/swift that referenced this pull request Feb 24, 2026
A nonescaping closure that returns a ~Escapable result and has no @_lifetime
annotation is assumed to depend on its closure context.

This fixes overly strict type checking introduced by:

    commit e98a7a6
    Date:   Fri Feb 6 02:09:25 2026
    Merge pull request swiftlang#86842
    LifetimeDependence: Support function types

Fix:

1. Disable missing dependency diagnostics for ~Escapable results

Continue allow the most basic nonescaping closure types without annotation:

    func f(body: () -> NE) -> NE

2. Disable single-parameter inference for function types

Do *not* infer a default parameter dependency here:

    func f(body: (AnyObject) -> NE) -> NE

The single-parameter rule should only apply to unambiguous function
declarations. It never applies to function types. Function types should instead
infer a dependency on the closure context.

Fixes rdar://171031632 ([nonescapable] allow nonescaping closures to return
non-Escapable types)
atrick added a commit to atrick/swift that referenced this pull request Feb 25, 2026
A nonescaping closure that returns a ~Escapable result and has no @_lifetime
annotation is assumed to depend on its closure context.

This fixes overly strict type checking introduced by:

    commit e98a7a6
    Date:   Fri Feb 6 02:09:25 2026
    Merge pull request swiftlang#86842
    LifetimeDependence: Support function types

Fix:

1. Disable missing dependency diagnostics for ~Escapable results

Continue allow the most basic nonescaping closure types without annotation:

    func f(body: () -> NE) -> NE

2. Disable single-parameter inference for function types

Do *not* infer a default parameter dependency here:

    func f(body: (AnyObject) -> NE) -> NE

The single-parameter rule should only apply to unambiguous function
declarations. It never applies to function types. Function types should instead
infer a dependency on the closure context.

Fixes rdar://171031632 ([nonescapable] allow nonescaping closures to return
non-Escapable types)
nickolas-pohilets pushed a commit to nickolas-pohilets/swift that referenced this pull request Mar 1, 2026
A nonescaping closure that returns a ~Escapable result and has no @_lifetime
annotation is assumed to depend on its closure context.

This fixes overly strict type checking introduced by:

    commit e98a7a6
    Date:   Fri Feb 6 02:09:25 2026
    Merge pull request swiftlang#86842
    LifetimeDependence: Support function types

Fix:

1. Disable missing dependency diagnostics for ~Escapable results

Continue allow the most basic nonescaping closure types without annotation:

    func f(body: () -> NE) -> NE

2. Disable single-parameter inference for function types

Do *not* infer a default parameter dependency here:

    func f(body: (AnyObject) -> NE) -> NE

The single-parameter rule should only apply to unambiguous function
declarations. It never applies to function types. Function types should instead
infer a dependency on the closure context.

Fixes rdar://171031632 ([nonescapable] allow nonescaping closures to return
non-Escapable types)
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.

5 participants