Commit Graph

3153 Commits

Author SHA1 Message Date
Michael Gottesman
eec57ce8c7 Merge pull request #87008 from gottesmm/pr-85ea95f09d9dc99ec128e346f5f11cfcf0cd0e3b
[rbi] Remove old check lines that no longer are tested anymore.
2026-02-05 16:26:52 -08:00
Pavel Yaskevich
527ab6386a Merge pull request #86967 from xedin/rdar-164077275
[Concurrency] A few fixes for default isolation inference
2026-02-05 15:31:10 -08:00
Michael Gottesman
903fa6a6e3 [rbi] Remove old check lines that no longer are tested anymore. 2026-02-05 09:51:35 -08:00
Pavel Yaskevich
bdd17e47b3 Merge pull request #86904 from xedin/rdar-148395744
[Concurrency] Fix thunk emission for function types with isolated par…
2026-02-05 07:01:46 -08:00
Michael Gottesman
82fa88a855 [rbi] Fix logic around tracking of Sendable/non-Sendable field projections from Sendable/non-Sendable values
Previously, region-based isolation was not diagnosing cases where a non-Sendable
value projected from a Sendable base that was MainActor isolated. For example:

```swift
@MainActor
struct MainActorBox {
  var value: NonSendableKlass?

  mutating func take() -> sending NonSendableKlass {
    if let value {
      self.value = nil
      return value // Should warn: main actor-isolated value cannot be 'sending'
    } else {
      preconditionFailure("Consumed twice")
    }
  }
}
```

This was caused by two issues:

1. A logic bug in `AddressBaseComputingVisitor::visitAll` where we overwrote an
   already-found Sendable value when recursing. The visitor should only record
   the first Sendable value found, not subsequent ones. This caused us to
   incorrectly return the `@MainActor` `MainActorBox` as the base instead of
   emitting a require for the projected value.

2. struct_element_addr being transparent unconditionally causing us to not even
   emit a require at all.

This commit has two parts:

1. I fixed the first two issues by fixing the logic bug and by making
   struct_element_addr only transparent if its operand and result are
   non-Sendable. I added logic that we have used in other such cases to handle
   non-Sendable operand/Sendable result as well as Sendable operand and
   non-Sendable result. I then added the same support for tuple_element_addr and
   unchecked_take_enum_data_addr since they suffered from a similar problem.

2. Adding the logic to handle variants where the operand was non-Sendable and
   the result was Sendable, caused a bunch of tests to break so I had to fix
   that.

To fix the broken test cases, I had to make the compiler smarter about how it
was inserting this require. To do this:

1. I checked if the access base of the projection was actually immutable or if
   we are an alloc_stack that there was a prefix path in the projection path of
   immutable projections that end in the alloc_stack. In such a case, we know
   that we do not need to require that the operand is available in the current
   isolation domain since we will never write to that piece of memory and once
   we have loaded the result from memory, we know that the value is Sendable so
   nothing bad can happen.

2. If the access base of the projection was mutable, I used the same logic that
   we used for alloc_box that were non-Sendable that stored a Sendable thing by
   changing operand to be a `require [mutable_base_of_sending]` on the result of
   the projection instead of requiring the projection's operand. This ensures
   that we handled important flow sensitive cases.

rdar://169626088
2026-02-04 09:33:58 -08:00
Hamish Knight
746f011cd0 Merge pull request #77063 from jamieQ/jquadri/warn-weak-to-strong-capture
[Sema]: diagnose implicit strong captures of weak capture list entries
2026-02-04 14:55:58 +00:00
Michael Gottesman
52a33beec0 Merge pull request #86946 from gottesmm/pr-fb033d6ec27597054d09c768a52a3a97dd3d81e0
[rbi] Use indirect assignment for stores to no-alias destinations to fix a common data race hole
2026-02-03 21:21:43 -08:00
Doug Gregor
c88519a83b Reject @isolated(any) when we don't have the concurrency library
IRGen crashes on @isolated(any) functions if the Actor protocol isn't
available. It's safer to reject in the type checker in these cases.

Fixes rdar://165090740.
2026-02-03 16:14:38 -08:00
Jamie
f9e41569f1 [Sema]: diagnose implicit strong captures of weak capture list items
Add a diagnostic for when a weak or unowned capture list item binds a
referent that is implicitly strongly captured in an outer escaping
closure.
2026-02-03 16:21:20 -06:00
Pavel Yaskevich
721723fe9b [Concurrency] DefaultIsolation: Add isolation attributes to declarations inferred as @MainActor
When declaration gets inferred as `@MainActor` that needs to be
reflected in its attributes as well because that's the only reliable
way propagate isolation across modules.

Resolves: rdar://164077275
2026-02-03 13:08:04 -08:00
Michael Gottesman
192344076f [rbi] Use translateSILAssignIndirect for stores to no-alias destinations
For stores to unaliased, non-aggregate-projected destinations, switch from
translateSILAssignDirect(destValue, src) to translateSILAssignIndirect(dest, src).
This passes the Operand* rather than just the SILValue, enabling proper tracking
of the destination address in region analysis.

First in a series migrating instruction handlers to indirect assignment.

NOTE: I originally thought that pack_element_set would also have this property,
but alloc_pack today is always assumed to be to be MayAlias and thus we emit a
merge. I think this is fine since one can never actually assign over a pack
variable like one can other things (that is I think they are generally just used
for marshalling and the like). If I am wrong, I can just fix it later.

rdar://156024613
https://github.com/swiftlang/swift/issues/83121
2026-02-03 09:00:27 -08:00
Michael Gottesman
2016d952bb [rbi] Make select_enum and select_enum_addr both assign instructions.
I looked at the implementation and it was basically an assign. There is no
reason not to just eliminate the special implementation.
2026-02-02 10:38:03 -08:00
Pavel Yaskevich
7aa76870ee Merge pull request #86875 from xedin/issue-83790
[Concurrency] Diagnose more places where isolation on `main` is invalid
2026-01-30 15:06:45 -08:00
Pavel Yaskevich
613f4eafa2 [Concurrency] Fix thunk emission for function types with isolated parameters
This is important for things like instance methods of actors in
particular because otherwise it won't be possible to compute a
correct isolation for the thunk.

This fix enables fully unapplied references to actor-isolated
instance methods and other functions with isolated parameters.

Resolves: rdar://148395744
2026-01-30 14:55:42 -08:00
Pavel Yaskevich
03c6e38169 Merge pull request #86874 from xedin/rdar-168238300
[Concurrency] Narrow fix to break cycles in implicit Sendab…
2026-01-30 08:49:48 -08:00
Pavel Yaskevich
bbb078ccde [Concurrency] Narrow fix to break cycles in implicit Sendable inference
An internal type is inferred to be Sendable when it's instance storage
as Sendable. This complicates conformance lookup because all of the
additional checking has to happen there. `lookupConformance` already
has a check that breaks cycles with implicit known protocols, this
was defeated by tuple types at the moment because they are split later
by recursively calling `lookupConformance`.

One idea was to split storage checking out of lookup and do that as
part of availability checking but that won't help when check is requested
from SILGen or type is a in different file from its use.

As a narrow fix the change checks individual elements of tuple types
in `diagnoseNonSendableTypes` that helps to detect cycles early.

Resolves: https://github.com/swiftlang/swift/issues/62060
Resolves: https://github.com/swiftlang/swift/issues/82628
Resolves: rdar://168238300
2026-01-29 11:40:32 -08:00
Pavel Yaskevich
9d6cdb0303 [Concurrency] Diagnose more places where isolation on main is invalid
Previously only the use a global actor different from
`MainActor` was diagnosed, now any attempt to use an
explicit isolation attribute that differs from `@MainActor`
would be as well.

Resolves: https://github.com/swiftlang/swift/issues/83790
Resolves: rdar://158608620
2026-01-29 11:37:36 -08:00
Xi Ge
4a44642fac Merge pull request #86717 from sepy97/fix_attributes_printer
ASTPrinter: skip printing incompatible attributes in swiftinterface
2026-01-28 21:10:47 -08:00
Sam Pyankov
1c2cb16a6a ASTPrinter: skip printing incompatible attributes in swiftinterface
Attributes that can not appear on declaration should not be printed in textual interface
rdar://164975727
2026-01-28 15:48:21 -08:00
Alastair Houghton
064860825a Merge pull request #86808 from al45tair/eng/PR-168508495-main
[Concurrency] Mark custom executors entry points as SPI.
2026-01-28 09:08:44 +00:00
Doug Gregor
17b333d3c5 Merge pull request #86820 from DougGregor/task-cancellation-handler-with-isolation
Reinstate public API for `withTaskCancellationHandler(operation:onCancel:isolation:)`
2026-01-27 14:31:39 -08:00
Doug Gregor
43217e190d Reinstate public API for withTaskCancellationHandler(operation:onCancel:isolation:)
Some clients are explicitly passing isolation through, so we need to
retain this signature. Fixes rdar://168955495.
2026-01-27 09:41:20 -08:00
Alastair Houghton
61cab14821 [Concurrency] Mark custom executors entry points as SPI.
Marking these as `@_spi(ExperimentalCustomExecutors)` for now, to match
what we're doing for 6.3.

rdar://168508495
2026-01-27 09:48:01 +00:00
elsa
5e9f215f31 Merge pull request #86010 from elsakeirouz/rework-for-each-desugar
Rework ForEachStmt Desugaring
2026-01-24 13:55:51 +00:00
Elsa Keirouz
d54a572f7f [Sema] desugar ForEachStmt at AST level 2026-01-23 15:17:29 +00:00
eeckstein
ee398d1b18 Merge pull request #86644 from eeckstein/lifetime-completion
Optimizer: enable complete OSSA lifetimes throughout the pass pipeline
2026-01-23 06:14:10 +01:00
Michael Gottesman
6b5fbacf21 Merge pull request #86704 from gottesmm/pr-82c6cf1e5fb
[rbi] Preparatory work for splitting indirect and direct assigns.
2026-01-22 19:36:08 -08:00
Erik Eckstein
0f0aa0c17b Optimizer: require that there are no unreachable blocks and infinite loops in OSSA
These two new invariants eliminate corner cases which caused bugs if optimization didn't handle them.
Also, it will significantly simplify lifetime completion.

The implementation basically consists of these changes:
* add a flag in SILFunction which tells optimization if they need to take care of infinite loops
* add a utility to break infinite loops
* let all optimizations remove unreachable blocks and break infinite loops if necessary
* add verification to check the new SIL invariants

The new `breakIfniniteLoops` utility breaks infinite loops in the control flow by inserting an "artificial" loop exit to a new dead-end block with an `unreachable`.
It inserts a `cond_br` with a `builtin "infinite_loop_true_condition"`:
```
bb0:
  br bb1
bb1:
  br bb1              // back-end branch
```
->
```
bb0:
  br bb1
bb1:
  %1 = builtin "infinite_loop_true_condition"() // always true, but the compiler doesn't know
  cond_br %1, bb2, bb3
bb2:                  // new back-end block
  br bb1
bb3:                  // new dead-end block
  unreachable
```
2026-01-22 17:41:23 +01:00
Michael Gottesman
6d858cbd5f [rbi] In preparation for splitting AssignDirect and AssignIndirect begin testing directly how we convert SIL instructions into partition ops.
This is to ensure that I am not breaking anything when I am making this change.
We should have had this testing for a long time anyways.
2026-01-22 06:06:18 -08:00
Michael Gottesman
5d1f72f5d1 [rbi] Treat alloc_box { let TYPE } where TYPE is Sendable as Sendable
This is safe because:

1. The box can never be written to after initialization due to
definite initialization, and that initialization must occur before the box
escapes to another isolation domain.

2. We restrict this to immutable boxes containing Sendable types since otherwise
we could load a non-Sendable value from the box and produce a fresh value that
could escape into multiple isolation domains, potentially allowing unsafe
concurrent writes.

The important use case that this fixes are as follows:

1. Sendable noncopyable nominal types. Since the type is noncopyable, we must
   store it into a let box it to capture it in an escaping closure causing us to
   previously error:

   ```swift
   func testNoncopyableSendableStructWithEscapingMainActorAsync() {
     let x = NoncopyableStructSendable()
     let _ = {
       escapingAsyncUse { @MainActor in
         useValue(x) // Error!
       }
     }
   }
   ```

2. Simple capture lists of Sendable noncopyable nominal types. When we put the
   value into the capture list, we create a new let binding for the value which
   would be a let box since the underlying type is noncopyable:

   ```swift
   func testNoncopyableSendableStructWithEscapingMainActorAsyncNormalCapture() {
     let x = NoncopyableStructSendable()
     let _ = { [x] in
       escapingAsyncUse { @MainActor in
         useValue(x)
       }
     }
   }
   ```

Originally developed as part of rdar://166081666, though it turned out to be
independent of that fix.
2026-01-20 15:43:13 -08:00
Michael Gottesman
8fed053bbc Merge pull request #86585 from gottesmm/pr-59b10ee5ed1bbeaab56ca9dad42157d6b666f4aa
[silgen] Look through conversions that combine a Sendable and nonisolated(nonsending) conversion.
2026-01-20 10:30:58 -08:00
Pavel Yaskevich
6f52c33b77 Merge pull request #86625 from xedin/unfix-strip-concurrency-for-mangling
[ASTMangler] Restore `stripConcurrency` behavior for `@preconcurrency…
2026-01-19 08:13:11 -08:00
Daniel Rodríguez Troitiño
67836a82d6 Runtime: Mark demangling test as requiring the runtime_module (#86604)
Otherwise the test will try to execute in configurations that do not
build the runtime module, and will fail to pass.
2026-01-18 20:35:24 -08:00
Hamish Knight
df187348bc [test] Add some extra for loop tests
Add some test cases that were uncovered when doing source compatibility
testing for the for loop rework.
2026-01-18 23:25:52 +00:00
Pavel Yaskevich
6487b433c0 [ASTMangler] Restore stripConcurrency behavior for @preconcurrency declarations
This is a follow-up to https://github.com/swiftlang/swift/pull/86557

When mangling a `@preconcurrency` declaration, `dropGlobalActor`
is set to `true`, and the original condition behind that used to
remove isolation from function types regardless of whether the
function type was actually global-actor isolated or not. We need
to maintain this behavior for mangling or risk breaking ABI for
the existing declarations that had isolation like `@isolated(any)`.
2026-01-17 18:28:07 -08:00
Michael Gottesman
56d6b60c36 Merge pull request #86312 from gottesmm/rdar166081666
[rbi] Convert Sendable immutable weak var captures to weak let to fix RegionIsolation checking
2026-01-17 11:38:12 -08:00
Michael Gottesman
7d0aec4f4b Return to some tests in transfernonsendable_closure_captures.swift back to their state so it passes in ToT.
I have a patch out of tree that fixes these tests so that the error is not
emitted. But to make the overall change cherry-pickable, I decided to leave out
that change. Once the main change lands, I will commit the other change and
remove these diagnostics from the test file.
2026-01-16 09:58:01 -08:00
Michael Gottesman
0ce3729740 [rbi] Mark mutable weak capture boxes containing Sendable types as immutable if they are never interprocedurally written to and teach SILIsolationInfo::isSendable that they are meant to be treated as Sendable.
The pass works by walking functions in the modules looking for mutable alloc_box
that contains a weak variable and is knowably a capture. In such a case, the
pass checks all uses of the alloc_box interprocedurally including through
closures and if provably immutable marks the box and all closure parameters as
being inferred immutable.

This change also then subsequently changes SILIsolationInfo to make it so that
such boxes are considered Sendable in a conservative manner that pattern matches
the weak reference code emission pretty closely.

The reason why I am doing this is that issue #82427 correctly tightened region
isolation checking to catch unsafe concurrent access to mutable shared
state. However, this introduced a regression for a common Swift pattern:
capturing `self` weakly in escaping closures.

The problem occurs because:

1. Weak captures are stored in heap-allocated boxes.
2. By default, these boxes are **mutable** (`var`) even if never written to after initialization
3. Mutable boxes are non-Sendable (they could be unsafely mutated from multiple threads)
4. Region isolation now correctly errors when sending non-Sendable values across isolation boundaries

This breaks code like:

```swift
@MainActor class C {
    func test() {
        timer { [weak self] in  // Captures self in a mutable box
            Task { @MainActor in
                self?.update()  // ERROR: sending mutable box risks data races
            }
        }
    }
}
```

Note how even though `self` is Sendable since it is MainActor-isolated, the *box
containing* the weak reference is not Sendable because it is mutable.

With the change in this commit, we now recognize that the box can safely be
treated as Sendable since we would never write to it.

rdar://166081666
2026-01-16 09:58:01 -08:00
Doug Gregor
9d2f528f08 Merge pull request #85518 from DougGregor/task-cancellation-rethrows-nonisolated-nonsending
[Concurrency] Adopt typed throws and nonisolated(nonsending) in withTaskCancellationHandler
2026-01-16 02:14:15 -08:00
Michael Gottesman
d1e3dfe5c9 [silgen] Look through conversions that combine a Sendable and nonisolated(nonsending) conversion.
These conversions are artificial conversions inserted by Sema since isolation is
not represented on interface types. We previously looked though:

1. A single conversion that added nonisolated(nonsending).
2. A two level conversion where the first conversion added Sendable and the
second added nonisolated(nonsending).

In this case, Sema is generating a single conversion that combines the Sendable
and isolation conversion.

To be consistent, I also updated the code that involved conversion from
execution caller to global actor as well in case we hit the same case there.

https://github.com/swiftlang/swift/issues/83812
rdar://158685169
2026-01-15 13:29:21 -08:00
Owen Voorhees
4f0b627d6d Revert "[Concurrency] Adopt typed throws in Task creation APIs (#84802)"
This reverts commit dc2d6fb4af.
2026-01-15 13:10:36 -08:00
Doug Gregor
0aac69bd35 [Task cancellation] Adopt nonisolated(nonsending) and sending 2026-01-14 15:57:40 -08:00
Doug Gregor
94ec6bc6ed [Concurrency] Adopt typed throws and nonisolated(nonsending) in withTaskCancellationHandler
Replace the use of rethrows and #isolation in
withTaskCancellationHandler with typed throws and
nonisolated(nonsending), respectively.

Fixes rdar://146901428.
2026-01-14 15:57:39 -08:00
Konrad `ktoso` Malawski
40dabefdb4 Reapply: Runtime: expose demangle() in Runtime module (#84788) (#86510) 2026-01-14 21:44:28 +09:00
Konrad `ktoso` Malawski
dc2d6fb4af [Concurrency] Adopt typed throws in Task creation APIs (#84802) 2026-01-13 20:21:20 +09:00
eeckstein
4766678f3f Revert "Runtime: expose demangle() in Runtime module (#84788)"
This reverts commit ab69fc0d2c.
2026-01-12 10:26:14 +01:00
Konrad `ktoso` Malawski
ab69fc0d2c Runtime: expose demangle() in Runtime module (#84788)
We should expose the demangle functionality; It's been widely used by
calling into internal _swift_demangle and instead we should offer a real
API. It's also already used in the Runtime module already when forming
backtraces.

[Previous
discussions](https://forums.swift.org/t/demangle-function/25416/15)
happened between 2019 and 2024, and just never materialized in a
complete implementation and proposal.

Right now, even more tools are in need of this API, as we are building
continious profiling solutions etc, so it is a good time to revisit this
topic.

This PR is roughly based off @Azoy's

https://github.com/swiftlang/swift/pull/25314/files#diff-fd379a721cc9a1c9ef6486eae713e945da842b42170d4d069029a57334371eba
from 2019, however it brings it over to the new Runtime module which is
a great place to put this functionality - even Backtrace had to recently
reinvent calling the demangling infra in this module.

Pending SE review, [proposal
here](https://github.com/swiftlang/swift-evolution/pull/2989).

cc @azoy @al45tair

---------

Co-authored-by: Alastair Houghton <alastair@alastairs-place.net>
2026-01-09 09:46:19 -08:00
Pavel Yaskevich
541b7afdb4 Merge pull request #86334 from xedin/rdar-167050741
[AST] ASTPrinter: Don't attempt to print `nonisolated(nonsending)` on…
2026-01-09 07:45:26 -08:00
Hamish Knight
777b4c3ca2 Merge pull request #86304 from hamishknight/at-request
[Serialization] Ensure semantic attributes are serialized
2026-01-08 04:14:44 +00:00
Hamish Knight
dc4b144441 Merge pull request #86294 from hamishknight/diag-tweaks
[Diags] A couple of diagnostic engine fixes
2026-01-08 01:19:27 +00:00