C code is highly likely to want to use pointers as references between dependent
structs, and we would like to be able to readily map these to lifetime-dependent
Swift values. Making C types addressable-for-dependencies ensures that any function
producing a dependency on such a value receives a stable in-memory address for that
value, allowing borrows and inout accesses to always be representable as pointers.
rdar://153648393
Explanation: C++ namespaces imported as Swift enums. This was not
accounted for in a condition and that resulted in not importing lifetime
annotations for functions that are in namespace scope. This PR fixes
that condition.
Issue: rdar://149756644
Risk: Low, the fix is very targeted.
Testing: Regression test added.
Original PR: #80986
Reviewer: @j-hui
Importing these annotations were behind the LifetimeDependence
experimental flag. However, this feature flag is intended to guard the
use of @lifetime annotations on the Swift side and lifetime inference.
The checking of imported lifetime contracts should work even when this
flag is off. Removing the flag from the importer caused some fallout.
This was mostly due to calling getInterfaceType functions before the
import of some Swift declarations were fully done so the code was
slightly improved to make decisions only based on the C++ types.
There was also a crash when on-member functions imported as methods into
Swift. That is worked around in this PR.
There is one last feature check that we cannot remove yet, we generate
@lifetime annotations in the SwiftifyImport macro.
C++ code can return values that depend on the storage that backs the
references that were passed in as argument. Thus, swift should not
introdue temporary copies of that storage before invoking those
functions as they could result in lifetime issues.
We do not need to borrow from view objects passed by value but we need
to borrow from owners taken by const reference regardless of whether it
was annotated using lifetimebound or lifetime_capture_by.
ClangImporter will generate value and default initializers for certain
structs imported from C++. These generated initializers have no
associated lifetime dependence information so they will trigger spurious
errors for non-escapable types. This patch makes sure these are marked
as unsafe so the type checker will not generate errors for them.
Moreover, the generated default initializer would trigger a crash for
non-escapable types as the builtin to zero initialize an object does not
support non-escapable types yet.
rdar://143040862
Non-escapable types are now enabled by default. Use the new lifetime
dependence feature flag to gate interpreting lifetime annotations on the
C++ side and add tests to make sure we get the expected diagnostics when
the feaature flag is off.
Find all the usages of `--enable-experimental-feature` or
`--enable-upcoming-feature` in the tests and replace some of the
`REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which
should correctly apply to depending on the asserts/noasserts mode of the
toolchain for each feature.
Remove some comments that talked about enabling asserts since they don't
apply anymore (but I might had miss some).
All this was done with an automated script, so some formatting weirdness
might happen, but I hope I fixed most of those.
There might be some tests that were `REQUIRES: asserts` that might run
in `noasserts` toolchains now. This will normally be because their
feature went from experimental to upcoming/base and the tests were not
updated.
The semantics of returning independent value already matches what
immortal lifetimes are within Swift. This patch makes sure this
annotation works as expected with non-escapable types.
rdar://137671642
Lifetime dependencies in SIL tests continue to be represented as a type modifier on the target.
As before, they are represented as a LifetimeDependentTypeRepr in the AST.
The lifetimebound annotations are now imported as lifetime dependencies.
This works for basic cases but there are still some parts missing:
* Support lifeitmebound annotations on constructors
* A way to represent immortal/static lifetimes on the C++ side