Commit Graph

6772 Commits

Author SHA1 Message Date
Pavel Yaskevich
785e7b1571 Merge pull request #82858 from gottesmm/rdar154969621
[concurrency] Perform some fixes so that transfernonsendable_closureliterals_isolationinference.swift now passes.
2025-07-08 00:04:14 -07:00
Konrad `ktoso` Malawski
e9a35c0003 Merge pull request #82865 from ktoso/wip-stronger-assert 2025-07-08 15:38:34 +09:00
Konrad `ktoso` Malawski
c6f223f57a Merge pull request #82793 from ktoso/wip-correct-isolated-handling-with-caller-isolation 2025-07-08 12:01:54 +09:00
Konrad 'ktoso' Malawski
4a5ccf04a7 [Concurrency] Use ASSERT for to also assert in release builds
Small cleanup from code review; we'd crash either way after this line,
so might be better to always ASSERT more nicely.
2025-07-08 10:03:41 +09:00
Michael Gottesman
648bb8fe30 [concurrency] Perform some fixes so that transfernonsendable_closureliterals_isolationinference.swift now passes.
The reason why this failed is that concurrently to @xedin landing
79af04ccc4, I enabled
NonisolatedNonsendingByDefault on a bunch of other tests. That change broke the
test and so we needed to fix it.

This commit fixes a few issues that were exposed:

1. We do not propagate nonisolated(nonsending) into a closure if its inferred
context isolation is global actor isolated or if the closure captures an
isolated parameter. We previously just always inferred
nonisolated(nonsending). Unfortunately since we do not yet have capture
information in CSApply, this required us to put the isolation change into
TypeCheckConcurrency.cpp and basically have function conversions of the form:

```
(function_conversion_expr type="nonisolated(nonsending) () async -> Void"
   (closure_expr type="() async -> ()" isolated_to_caller_isolation))
```

Notice how we have a function conversion to nonisolated(nonsending) from a
closure expr that has an isolation that is isolated_to_caller.

2. With this in hand, we found that this pattern caused us to first thunk a
nonisolated(nonsending) function to an @concurrent function and then thunk that
back to nonisolated(nonsending), causing the final function to always be
concurrent. I put into SILGen a peephole that recognizes this pattern and emits
the correct code.

3. With that in hand, we found that we were emitting nonisolated(nonsending)
parameters for inheritActorContext functions. This was then fixed by @xedin in

With all this in hand, closure literal isolation and all of the other RBI tests
with nonisolated(nonsending) enabled pass.

rdar://154969621
2025-07-07 17:21:41 -07:00
Allan Shortlidge
6e08b8980f SILGen: Refactor emission of availability checks.
Generalize SILGen for `if #available` checks by delegating the determination of
the query function and its arguments to `AvailabilityQuery`. Update SILGen for
`@backDeployed` thunks to use the same infrastructure.

NFC.
2025-07-06 19:44:53 -07:00
Allan Shortlidge
a4f59f9481 AST: Return @backDeployed attribute along with version from Decl query.
Also, introduce a convenience on `BackDeployedAttr` for getting its associated
`AvailabilityDomain`.

NFC.
2025-07-06 19:44:53 -07:00
Konrad 'ktoso' Malawski
b1ca06d79d [Concurrency] #isolation+nonsending nonisolated - review followup and SIL test 2025-07-07 11:37:16 +09:00
Konrad 'ktoso' Malawski
b0d2ca9be6 [Concurrency] Fix nonisolated(nonsending) interaction with #isolation 2025-07-04 10:20:08 +09:00
Allan Shortlidge
ede7bdb5d7 Merge pull request #82671 from tshortli/zippered-miscompile-if-unavailable
SILGen: Fix `if #unavailable` mis-compile for zippered libraries
2025-07-02 16:05:51 -07:00
John McCall
834b606c13 Correctly forward the implicit nonisolated(nonsending) parameter in thunks (#82705)
Also, I discovered that we don't apply nonisolated(nonsending) to
function types in the new mode. That's one for a different patch.

Fixes rdar://154401813 and rdar://154137740
2025-07-02 12:03:59 -07:00
Allan Shortlidge
4a76c04cf5 SILGen: Fix if #unavailable mis-compile for zippered libraries.
Inverted availability queries were mis-compiled for zippered libraries because
the code that emits calls to `isOSVersionAtLeastOrVariantVersionAtLeast()` was
not updated when the `if #unavailable` syntax was introduced (at that time
support for zippered libraries had not yet been upstreamed). The result of
these calls is now inverted when appropriate.

To make it easier to manage the growing complexity of supporting availability
queries, Sema now models the relevant information about an availability query
with the new `AvailabilityQuery` type. It encapsulates the domain for the
query, the result if it is known at compile time, and the version tuple
arguments to pass to a runtime invocation if applicable.

Resolves rdar://147929876.
2025-07-02 11:23:42 -07:00
Doug Gregor
7789a0ce64 [SE-0371] Back-deploy support for main-actor-isolated deinit
When targeting a platform that predates the introduction of isolated
deinit, make a narrow exception that allows main-actor-isolated deinit
to work through a special, inlineable entrypoint that is
back-deployed. This implementation

  1. Calls into the real implementation when available, otherwise
  2. Checks if we're on the main thread, destroying immediately when
we are, otherwise
  3. Creates a new task on the main actor to handle destruction.

This implementation is less efficient than the implementation in the
runtime, but allows us to back-deploy this functionality as far back
as concurrency goes.

Fixes rdar://151029118.
2025-06-30 17:38:08 -07:00
John McCall
c8889b3c6e Merge pull request #82592 from rjmccall/local-function-isolation-fixes
Local function isolation fixes
2025-06-30 01:47:45 -04:00
John McCall
3439e0caab Fix a bunch of bugs with the isolation of local funcs. Since we
use local funcs to implement `defer`, this also fixes several
bugs with that feature, such as it breaking in nonisolated
functions when a default isolation is in effect in the source file.

Change how we compute isolation of local funcs. The rule here is
supposed to be that non-`@Sendable` local funcs are isolated the
same as their enclosing context. Unlike closure expressions, this
is unconditional: in instance-isolated functions, the isolation
does not depend on whether `self` is captured. But the computation
was wrong: it didn't translate global actor isolation between
contexts, it didn't turn parameter isolation into capture isolation,
and it fell through for several other kinds of parent isolation,
causing the compiler to try to apply default isolation instead.
I've extracted the logic from the closure expression path into a
common function and used it for both paths.

The capture computation logic was forcing a capture of the
enclosing isolation in local funcs, but only for async functions.
Presumably this was conditional because async functions need the
isolation for actor hops, but sync functions don't really need it.
However, this was causing crashes with `-enable-actor-data-race-checks`.
(I didn't investigate whether it also failed with the similar
assertion we do with preconcurrency.) For now, I've switched this
to capture the isolated instance unconditionally. If we need to
be more conservative by either only capturing when data-race checks
are enabled or disabling the checks when the isolation isn't captured,
we can look into that.

Fix a bug in capture isolation checking. We were ignoring captures
of nonisolated declarations in order to implement the rule that
permits `nonisolated(unsafe)` variables to be captured in
non-sendable closures. This check needs to only apply to variables!
The isolation of a local func has nothing to do with its sendability
as a capture.

That fix exposed a problem where we were being unnecessarily
restrictive with generic local func declarations because we didn't
consider them to have sendable type. This was true even if the
genericity was purely from being declared in a generic context,
but it doesn't matter, they ought to be sendable regardless.

Finally, fix a handful of bugs where global actor types were not
remapped properly in SILGen.
2025-06-29 01:23:04 -04:00
Doug Gregor
c0c7bf35d8 Merge pull request #82545 from DougGregor/silgen-skip-isolated-deinit
[SILGen] Ensure that we don't emit a skipped isolated deinit
2025-06-27 18:49:50 -07:00
John McCall
2eee30dfbe [NFC] Encapsulate the parameter index of an ActorIsolation 2025-06-27 19:48:12 -04:00
Meghana Gupta
f19adcaf63 [NFC] Add a flag to print a function's ast before SILGen 2025-06-26 14:42:40 -07:00
Doug Gregor
95e4d3227e [SILGen] Ensure that we don't emit a skipped isolated deinit
Fixes rdar://154373088 / issue #82523
2025-06-26 14:01:22 -07:00
Allan Shortlidge
39b6c608b0 SILGen: Reorganize code related to availability.
NFC.
2025-06-23 15:57:34 -07:00
Allan Shortlidge
91043271fa SILGen: Rename SILGenBackDeploy.cpp to SILGenAvailability.cpp.
NFC.
2025-06-23 15:57:34 -07:00
Michael Gottesman
862ef621c7 [silgen] Make async_Main compatible with calling nonisolated(nonsending) functions.
The problem is that async_Main was setting an executor as its main executor
instead of an actor. This patch fixes the issue by just grabbing the main actor
instead.

rdar://153082633
2025-06-20 15:50:27 -07:00
Saleem Abdulrasool
3269c0649b SILGen: adjust check for optional-to-optional conversion (#82099)
The new macro aliasing uncovered a latent issue where we would attempt
to perform an optional-to-optional conversion on a type that is
non-optional though may be aliased to an optional. `CVaList` is
sometimes an optional pointer and would be interpreted as an optional
type which would fail the assertion in the optional-to-optional
conversion.
2025-06-18 09:52:41 -07:00
Joe Groff
761faaa169 SILGen: Handle struct fields and addressors as addressable storage.
When accessing stored properties out of an addressable variable or parameter
binding, the stored property's address inside the addressable storage of the
aggregate is itself addressable. Also, if a computed property is implemented
using an addressor, treat that as a sign that the returned address should be
used as addressable storage as well. rdar://152280207
2025-06-16 20:23:47 -07:00
Slava Pestov
28af54a778 Merge pull request #80913 from stzn/fix-crash-self-keypath-root
[SILGen]Check if baseType is DynamicSelfType
2025-06-06 22:35:47 -04:00
Michael Gottesman
4b06d1ecf4 Merge pull request #82029 from gottesmm/pr-4393908bd2ab4d5c84cd415ea5da407b148fceb1
[silgen] Teach SILGen how to emit a forced dynamic member ref given nonisolated(nonsending) casts.
2025-06-05 23:51:47 -07:00
Michael Gottesman
662dbdb55a [silgen] Teach SILGen how to emit a forced dynamic member ref given nonisolated(nonsending) casts.
Specifically, I taught SILGen how to emit an AST like the following:

```
(force_value_expr implicit type="nonisolated(nonsending) (Date?) async -> Void" implicit_iuo_unwrap
  (open_existential_expr implicit type="(nonisolated(nonsending) (Date?) async  -> Void)?"
    (opaque_value_expr implicit type="AnyObject")
    (declref_expr type="AnyObject" decl="test.(file).repro().anyObject@test.swift:6:7" function_ref=unapplied)
    (optional_evaluation_expr type="(nonisolated(nonsending) (Date?) async -> Void)?"
      (inject_into_optional type="(nonisolated(nonsending) (Date?) async -> Void)?"
        (function_conversion_expr type="nonisolated(nonsending) (Date?) async -> Void"
          (bind_optional_expr type="(Date?) async -> Void" depth=0
            (dynamic_member_ref_expr type="((Date?) async -> Void)?" decl="__ObjC.(file).Foo.start(at:)"
              (opaque_value_expr type="AnyObject"))))))))
```

Since we are emitting an objc async function, there isn't an extra implicit
parameter like if we were using a swift async function. So, I just reused code
that was already used locally to look through these sorts of conversions. I
just had to add to that code support for conversions that add
nonisolated(nonsending). Previously it only supported looking through global
actor conversions.

rdar://152596823
2025-06-05 13:34:42 -07:00
Doug Gregor
bc4cf1236b [SIL] Generalize CastingIsolatedConformances to CheckedCastInstOptions
We are going to need to add more flags to the various checked cast
instructions. Generalize the CastingIsolatedConformances bit in all of
these SIL instructions to an "options" struct that's easier to extend.

Precursor to rdar://152335805.
2025-06-04 17:12:28 -07:00
Pavel Yaskevich
e1e9f04398 Merge pull request #81863 from xedin/using-for-default-isolation-in-file-context
[AST/Sema] SE-0478:  Implement `using` declaration under an experimental flag
2025-06-02 09:56:29 -07:00
Joe Groff
209a7a2ef5 Merge pull request #81878 from jckarter/addressable-scope-for-captures
SILGen: Establish an addressability scope for closure captures.
2025-06-02 07:36:46 -07:00
Joe Groff
9904d6c318 SILGen: Establish an addressability scope for closure captures.
This allows a captured variable to serve as the root of an addressable dependency.
Fixes the compiler crash in rdar://150479326.
2025-05-30 14:03:27 -07:00
Kavon Farvardin
ec554da19a Merge pull request #81861 from kavon/kavon/avoid-double-copy
SILGen: avoid double copies with 'copy' expr
2025-05-30 03:57:46 -07:00
Pavel Yaskevich
aabfebec03 [AST] Add new declaration - using
Initially this declaration is going to be used to determine
per-file default actor isolation i.e. `using @MainActor` and
`using nonisolated` but it could be extended to support other
file-global settings in the future.
2025-05-30 00:39:06 -07:00
Kavon Farvardin
32f1ebcfab SILGen: avoid double copies with 'copy' expr 2025-05-29 19:47:26 -07:00
Joe Groff
22eb7e62d9 SILGen: Emit property descriptors for conditionally Copyable and Escapable types.
Key paths can't reference non-escapable or non-copyable storage declarations,
so we don't need to refer to them resiliently, and can elide their property
descriptors.

However, declarations may still be conditionally Copyable and Escapable, and
if so, then they still need a property descriptor for resilient key path
references. When a property or subscript can be used in a context where it
is fully Copyable and Escapable, emit the property descriptor in a generic
environment constrained by the necessary conditional constraints.

Fixes rdar://151628396.
2025-05-27 09:35:40 -07:00
Allan Shortlidge
4aa516aebb SILGen: Fix if #available for unavailable custom domains in zippered modules.
When generating SIL for an `if #available(SomeDomain)` query in code being
compiled for a zippered target, the generated code was mis-compiled if
`SomeDomain` were disabled at compile time. Empty version ranges need to be
handled explicitly by `SILGenFunction::emitZipperedOSVersionRangeCheck()`.

SILGen still miscompiles `if #unavailable` queries generally in code compiled
for a zippered target (rdar://147929876).

Resolves rdar://150888941.
2025-05-25 08:27:12 -07:00
Daniil Kovalev
1e403ecf5c [AutoDiff] Support custom derivatives for @_alwaysEmitIntoClient functions (#78908)
Consider an `@_alwaysEmitIntoClient` function and a custom derivative
defined
for it. Previously, such a combination resulted different errors under
different
circumstances.

Sometimes, there were linker errors due to missing derivative function
symbol -
these occurred when we tried to find the derivative in a module, while
it
should have been emitted into client's code (and it did not happen).

Sometimes, there were SIL verification failures like this:

```
SIL verification failed: internal/private function cannot be serialized or serializable: !F->isAnySerialized() || embedded
```

Linkage and serialization options for the derivative were not handled
properly,
and, instead of PublicNonABI linkage, we had Private one which is
unsupported
for serialization - but we need to serialize `@_alwaysEmitIntoClient`
functions
so the client's code is able to see them.

This patch resolves the issue and adds proper handling of custom
derivatives
of `@_alwaysEmitIntoClient` functions. Note that either both the
function and
its custom derivative or none of them should have
`@_alwaysEmitIntoClient`
attribute, mismatch in this attribute is not supported.

The following cases are handled (assume that in each case client's code
uses
the derivative).

1. Both the function and its derivative are defined in a single file in
   one module.

2. Both the function and its derivative are defined in different files
which
   are compiled to a single module.

3. The function is defined in one module, its derivative is defined in
another
   module.

4. The function and the derivative are defined as members of a protocol
extension in two separate modules - one for the function and one for the
   derivative. A struct conforming the protocol is defined in the third
   module.

5. The function and the derivative are defined as members of a struct
extension in two separate modules - one for the function and one for the
   derivative.

The changes allow to define derivatives for methods of `SIMD`.

Fixes #54445
<!--
If this pull request is targeting a release branch, please fill out the
following form:

https://github.com/swiftlang/.github/blob/main/PULL_REQUEST_TEMPLATE/release.md?plain=1

Otherwise, replace this comment with a description of your changes and
rationale. Provide links to external references/discussions if
appropriate.
If this pull request resolves any GitHub issues, link them like so:

  Resolves <link to issue>, resolves <link to another issue>.

For more information about linking a pull request to an issue, see:

https://docs.github.com/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue
-->

<!--
Before merging this pull request, you must run the Swift continuous
integration tests.
For information about triggering CI builds via @swift-ci, see:

https://github.com/apple/swift/blob/main/docs/ContinuousIntegration.md#swift-ci

Thank you for your contribution to Swift!
-->
2025-05-25 09:47:15 -04:00
Alastair Houghton
3305e89ff9 Merge pull request #81639 from swiftlang/revert-81472-eng/PR-151147606
Revert "[Concurrency] Add underscore prefixes for not yet official API."
2025-05-22 15:36:52 +01:00
Erik Eckstein
29541fa8f1 SILGen: use builtin prepareInitialization instead of zeroInitializer when generating SIL for Builtin.emplace
`zeroInitializer` is blocking optimizations, but it is not needed because the closure of `Builtin.emplace` will initialize the memory anyway.
We only need to tell mandatory passes that this memory should be treated as initialized.
2025-05-20 20:46:33 +02:00
Alastair Houghton
28732f4a8b Revert "[Concurrency] Add underscore prefixes for not yet official API." 2025-05-20 15:44:26 +01:00
Michael Gottesman
abcc134621 Merge pull request #81542 from gottesmm/rdar150209093_rdar151394209
[concurrency] Fix a few issues around not emitted correct protocol witness and vtable thunks for nonisolated(nonsending)
2025-05-19 10:43:18 -07:00
Erik Eckstein
ddbc3a2fad SILGen: insert an end_lifetime in the throw-branch of a Builtin.emplace
When the called closure throws an error, it needs to clean up the buffer.
This means that the buffer is uninitialized at this point.

We need an `end_lifetime` so that the move-only checker doesn't insert a wrong `destroy_addr` because it thinks that the buffer is initialized.

Fixes a mis-compile.

rdar://151461109
2025-05-16 21:54:39 +02:00
Michael Gottesman
ef23f97071 [silgen] Teach SILGen how to handle nonisolated(nonsending) thunking for vtables
This ensures that when we generate the vtable thunk for a
nonisolated(nonsending) override (or vis-a-versa), we get the ABI correct. I
also added tests for all of the relevant cases for vtables that we check for
protocols.

rdar://151394209
2025-05-15 14:11:55 -07:00
Michael Gottesman
ff1cbea576 [silgen] Begin placing isolation on protocol witness thunks.
This will cause tests today to crash since even though we are placing the
isolation now, to make it easier to read, I left in the old isolation selecting
code. This code uses the witness's isolation instead of the requirement's
isolation which is incorrect since the protocol witness thunk needs to look the
requirement from an ABI perspective since the two must be substitutable. The
crash comes from the ABI verification I added in earlier commits.
2025-05-15 14:10:43 -07:00
Alastair Houghton
7f97e8d10b Merge pull request #81472 from al45tair/eng/PR-151147606
[Concurrency] Add underscore prefixes for not yet official API.
2025-05-15 18:39:21 +01:00
Alastair Houghton
c0ccdffeb7 [Concurrency] Add underscore prefixes for not yet official API.
Custom main and global executors work hasn't passed Swift Evolution yet,
so we need to avoid leaking it as API until it does.

To that end, underscore all the things.

rdar://151147606
2025-05-14 11:57:06 +01:00
Erik Eckstein
d28384dbd7 SILGen: use vector_base_addr in InlineArray literals 2025-05-12 19:25:12 +02:00
Erik Eckstein
b3087e30e4 SILGen: suppor struct element address projections in emitBuiltinAddressOfBorrowBuiltins 2025-05-12 19:24:31 +02:00
Henrik G. Olsson
efd70b1f54 Prevent silgen for macro expansions with type errors (#81396)
Due to a bug in how macros on nodes imported from clang are evaluated,
their function body is not always type checked. This forces type
checking before silgen of a macro originating on a node imported from
clang, to prevent crashing in silgen.

rdar://150940383
2025-05-09 10:27:27 -07:00
Alejandro Alonso
02d9779ba3 Merge pull request #81184 from Azoy/no-more-is-array-type
[AST] Rename isArrayType and split the InlineArray portion
2025-05-08 20:52:51 -07:00