Commit Graph

275 Commits

Author SHA1 Message Date
Tim Kientzle
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Doug Gregor
d1ae73f436 Handle flow-sensitive #isolation in distributed actor initializers.
Distributed actors can be treated as actors by accessing the `asLocalActor`
property. When lowering `#isolation` in a distributed actor initializer,
use a separate builtin `flowSensitiveDistributedSelfIsolation` to
capture the conformance to `DistributedActor`, and have Definite
Initialization introduce the call to the `asLocalActor` getter when
needed.
2024-06-09 22:48:43 -07:00
Doug Gregor
956243cd7e Teach #isolation to respect the flow-sensitive nature of actor initializers
Actor initializers have a flow-sensitive property where they are isolated
to the actor being initialized only after the actor instance itself is
fully-initialized. However, this behavior was not being reflected in
the expansion of `#isolation`, which was always expanding to `self`,
even before `self` is fully formed.

This led to a source compatibility issue with code that used the async
for..in loop within an actor initializer *prior* to the point where the
actor was fully initialized, because the type checker is introducing
the `#isolation` (SE-0421) but Definite Initialization properly rejects
the use of `self` before it is initialized.

Address this issue by delaying the expansion of `#isolation` until
after the actor is fully initialized. In SILGen, we introduce a new
builtin for this case (and *just* this case) called
`flowSensitiveSelfIsolation`, which takes in `self` as its argument
and produces an `(any Actor)?`. Definite initialization does not treat
this as a use of `self`. Rather, it tracks these builtins and
replaces them either with `self` (if it is fully-initialized at this
point) or `nil` (if it is not fully-initialized at this point),
mirroring the flow-sensitive isolation semantics described in SE-0327.

Fixes rdar://127080037.
2024-06-07 14:54:20 -07:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Nate Chandler
5881ea43e7 [DI] Fix unfailable throw during super init.
When deallocating a partially allocated class in the trapping branch of
an unfailable cast, cast back down to the subclass which is being
partially deallocated before emitting the dealloc partial ref
instruction.
2024-04-21 20:56:39 -07:00
Nate Chandler
46ccdd6176 [NFC] DI: Used already existing local variable.
Rather than repeating the same expression that already defines it.
2024-04-19 16:57:20 -07:00
Konrad `ktoso` Malawski
6132386371 [Distributed] Complete handling of protocol calls and witnesses using adjusted mangling scheme (#72416) 2024-03-23 23:54:23 +09:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
John McCall
2f8a33cf0a Experimental type-checking support for @isolated(any) function types. 2024-02-06 22:54:27 -05:00
Holly Borla
47afd21d85 [Concurrency] Remove ActorIsolation::GlobalActorUnsafe. 2024-01-21 21:05:33 -08:00
Nate Chandler
9bb0187be1 [SILGen] Add begin_borrow [var_decl] lifetimes. 2023-11-28 07:26:09 -08:00
Michael Gottesman
b1f69030fc [region-isolation] When assigning RValues into memory, use tuple_addr_constructor instead of doing it in pieces.
I also included changes to the rest of the SIL optimizer pipeline to ensure that
the part of the optimizer pipeline before we lower tuple_addr_constructor (which
is right after we run TransferNonSendable) work as before.

The reason why I am doing this is that this ensures that diagnostic passes can
tell the difference in between:

```
x = (a, b, c)
```

and

```
x.0 = a
x.1 = b
x.2 = c
```

This is important for things like TransferNonSendable where assigning over the
entire tuple element is treated differently from if one were to initialize it in
pieces using projections.

rdar://117880194
2023-11-07 15:38:33 -08:00
Sophia Poirier
4c9a726183 nonisolated(unsafe) to opt out of strict concurrency static checking for global variables 2023-10-26 16:22:28 -07:00
swift-ci
f0bd604d71 Merge remote-tracking branch 'origin/main' into rebranch 2023-10-02 09:33:57 -07:00
Pavel Yaskevich
24c4fcc10e [DI] Fix check that ignores loads related to assign_or_init and assign_by_wrapper
For cases where init accessor field has a nonmutating set we need
ignore copies and borrows associated with load of "self" because
they are going to be erased together with the setter application
by DI.
2023-09-29 13:18:54 -07:00
swift-ci
c2d0ed607a Merge remote-tracking branch 'origin/main' into rebranch 2023-09-19 11:33:34 -07:00
Erik Eckstein
5bc036661c SIL optimizer: add the LetPropertyLowering pass
It lowers let property accesses of classes.
Lowering consists of two tasks:

* In class initializers, insert `end_init_let_ref` instructions at places where all let-fields are initialized.
  This strictly separates the life-range of the class into a region where let fields are still written during
  initialization and a region where let fields are truly immutable.

* Add the `[immutable]` flag to all `ref_element_addr` instructions (for let-fields) which are in the "immutable"
  region. This includes the region after an inserted `end_init_let_ref` in an class initializer, but also all
  let-field accesses in other functions than the initializer and the destructor.

This pass should run after DefiniteInitialization but before RawSILInstLowering (because it relies on `mark_uninitialized` still present in the class initializer).
Note that it's not mandatory to run this pass. If it doesn't run, SIL is still correct.

Simplified example (after lowering):

  bb0(%0 : @owned C):                           // = self of the class initializer
    %1 = mark_uninitialized %0
    %2 = ref_element_addr %1, #C.l              // a let-field
    store %init_value to %2
    %3 = end_init_let_ref %1                    // inserted by lowering
    %4 = ref_element_addr [immutable] %3, #C.l  // set to immutable by lowering
    %5 = load %4
2023-09-19 15:10:30 +02:00
swift-ci
e72811e31e Merge remote-tracking branch 'origin/main' into rebranch 2023-09-09 10:13:45 -07:00
Holly Borla
a6d078b820 [Concurrency] Use the 'nonisolated' terminology instead of 'independent'.
This commit is NFC; it's mostly renames.
2023-09-08 13:28:55 -07:00
Sophia Poirier
86d368f364 Merge remote-tracking branch 'upstream/main' into fix-rebranch-automerger 2023-08-31 14:10:52 -07:00
Michael Gottesman
37d60a08bb [move-only] Rename mark_must_check -> mark_unresolved_non_copyable_value.
I was originally hoping to reuse mark_must_check for multiple types of checkers.
In practice, this is not what happened... so giving it a name specifically to do
with non copyable types makes more sense and makes the code clearer.

Just a pure rename.
2023-08-30 22:29:30 -07:00
swift-ci
0b0bb0b8b7 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-28 09:55:22 -07:00
Pavel Yaskevich
4ec86f222a [DI] InitAccessor: Ignore a load of "self" introduced by a partial apply of a setter
`nonmutating set` needs to load of "self" but that load could be
ignored safely because it's only viable when self is determined
to be fully initialized by DI. The same applies to `assign_by_wrapper`.
2023-08-25 09:49:31 -07:00
swift-ci
a083336db3 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-21 14:33:27 -07:00
Pavel Yaskevich
2149a4630a [DI] InitAccessors: Ignore unreachable blocks when check property initialization inside of an init accessor 2023-08-21 09:04:34 -07:00
swift-ci
ae4b70bf28 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-04 18:59:37 -07:00
Slava Pestov
9ebb5f2e03 AST: Rename VarDecl::getType() to VarDecl::getTypeInContext()
This is a futile attempt to discourage future use of getType() by
giving it a "scary" name.

We want people to use getInterfaceType() like with the other decl kinds.
2023-08-04 14:19:25 -04:00
Evan Wilde
fd156f2717 More APInt API updates
Updating more APInt and bit-manipulation API changes.
2023-07-25 12:28:27 -07:00
Pavel Yaskevich
00729ad958 Merge pull request #67107 from xedin/setterless-init-accessor-properties
[SILGen/DI] Add support for init accessor properties without setters
2023-07-07 00:16:07 -07:00
Pavel Yaskevich
a3e8bb6cce [DI] InitAccessors: Prevent re-initialization of init accessor property with a setter
Init accessor properties without setters behave just like `let` stored properties
and can only be initialized once.
2023-07-04 00:25:24 -07:00
Michael Gottesman
0e383cd918 [move-only] Fix a place in DI where we were not converting an assignable_but_not_consumable -> initable_but_not_consumable.
I fixed this for assign but missed a place where we needed to do the same thing for copy_addr.

rdar://111709236
2023-07-03 15:54:47 -07:00
Evan Wilde
250082df25 [NFC] Reformat all the LLVMs
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
2023-06-27 09:03:52 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Joe Groff
40ad5aaffc DefiniteInitialization: Error when noncopyable types are conditionally initialized.
This leads to unhandled complications in the move-only checker that were causing miscompiles.
We can disallow this for now. rdar://109695770
2023-06-16 17:13:38 -07:00
Pavel Yaskevich
2b8a39724c Merge pull request #66513 from xedin/init-accessor-diagnostics
[Sema/SIL] Improve diagnostics related to init accessors
2023-06-14 09:57:08 -07:00
Erik Eckstein
63808be395 DefinitInitialization: convert begin_access instructions of initializations to a static accesses
In case of `var` initializations, SILGen creates a dynamic begin/end_access pair around the initialization store.
If it's an initialization (and not a re-assign) it's guanranteed that it's an exlusive access and we can convert the access to an `[init] [static]` access.

https://github.com/apple/swift/issues/66496
2023-06-14 07:17:56 +02:00
Pavel Yaskevich
f6fd0bc1a7 [DI] InitAccessors: Enforce that @out parameters are fully initialized before every terminator
This closes a hole where an early return could leave some
properties from `initializes(...)` list uninitialized.

For example:

```swift
init(initialValue) initializes(_a, _b) {
  _a = initialValue.0
  if _a > 0 {
    return
  }

  _b = initialValue.1
}
```

Here `_b` is not initialized when `_a > 0`.
2023-06-13 10:58:50 -07:00
Pavel Yaskevich
c82559e33c [DI/Lowering] InitAccessors: Implement lowering of property assignments
DI marks all of of the previously initialized properties and Raw SIL
lowering emits `destroy_addr` before calling init accessor for such
properties to destroy previously set value.
2023-06-06 18:59:46 -07:00
Pavel Yaskevich
112d0d4f2d [DI] InitAccessors: Start marking initializes(...) properties as "out"
Adjust DI to recognize that "out" location without uses is uninitialized.
2023-06-06 18:59:45 -07:00
Pavel Yaskevich
68866d7ae5 [DI] InitAccessors: Handle assign_or_init without initializations
Introduce a placeholder "init" use anchored on `assign_or_init`
instruction to make sure that `handleStoreUse` gets a called and
sets the kind.
2023-06-06 18:59:13 -07:00
Pavel Yaskevich
fe90ddce74 [DI] InitAccessors: Implement handling of initializes/accesses attributes
- Record all properties listed in `accesses` as loads;
- Record all properties listed in `initialized` as init-or-assign;
- Detect situations when double-init could happen i.e. if one of
  the properties listed in `initializes` attribute is explicitly
  initialized before init accessor call.
2023-06-06 18:59:13 -07:00
Holly Borla
df69020eca [DefiniteInitialization] Lower AssignOrInit instructions to either call the
initializer or the setter closure with the given argument.
2023-06-06 18:59:13 -07:00
Holly Borla
0028bdf91d [DefiniteInitialization] Rename DIUseKind::AssignWrappedValue to DIUseKind::Set. 2023-06-06 18:59:13 -07:00
Holly Borla
684ef9c482 [AST] Add a new accessor kind for init accessors. 2023-06-06 18:57:31 -07:00
Michael Gottesman
d413b24e80 [move-only] Ensure that if we have an allocation that isn't fully initialized (and DI errors on it as such), the move checkers do not run on the allocation.
Previously we would crash.

Since we are relatively late in 5.9, my solution is to just turn off the move
checker on functions whenever DI would emit an error. If we were earlier in the
development cycle, then I would make the error be a per allocation change.

rdar://108993297
2023-05-08 13:32:06 -07:00
Doug Gregor
593c2364e8 [Macros] "Subsume" the initializer when an accessor macros adds non-observers
When an accessor macro adds a non-observing accessor to a property, it
subsumes the initializer. We had previously modeled this as removing
the initializer, but doing so means that the initializer could not be
used for type inference and was lost in the AST.

Explicitly mark the initializer as "subsumed" here, and be more
careful when querying the initializer to distinguish between "the
initializer that was written" and "the initializer that will execute"
in more places. This distinction already existed at the
pattern-binding level, but not at the variable-declaration level.

This is the proper fix for the circular reference issue described in
rdar://108565923 (test case in the prior commit).
2023-04-28 09:50:00 -07:00
Joe Groff
8e21bfcc47 MoveOnlyAddressChecker: Confine analysis to current formal access.
Code can only locally interact with a mutable memory location within a
formal access, and is only responsible for maintaining its invariants
during that access, so the move-only address checker does not need to,
and should not, observe operations that occur outside of the access
marked with the `mark_must_check` instruction. And for immutable
memory locations, although there are no explicit formal accesses, that's
because every access must be read-only, so although individual
accesses are not delimited, they are all compatible as far as
move-only checking is concerned. So we can back out the changes to SILGen
to re-project a memory location from its origin on every access, a
change which breaks invariants assumed by other SIL passes.
2023-04-02 16:33:57 -07:00
Michael Gottesman
43d8ab24f4 [move-only] Add a new type of mark_must_check initable_but_not_consumable.
This is used to teach the checker that the thing being checked is supposed to be
uninitialized at the mark_must_check point so that we don't put a destroy_addr
there.

The way this is implemented is that we always initially add
assignable_but_not_consumable but in DI once we discover that the assign we are
guarding is an init, we convert the assignable to its initable variant.

rdar://106525988
2023-03-31 17:32:58 -07:00
Pavel Yaskevich
e0bf2ff854 [SIL/DI] NFC: Remove TypeWrappers feature functionality 2023-02-08 10:14:29 -08:00
John McCall
d25a8aec8b Add explicit lowering for value packs and pack expansions.
- SILPackType carries whether the elements are stored directly
  in the pack, which we're not currently using in the lowering,
  but it's probably something we'll want in the final ABI.
  Having this also makes it clear that we're doing the right
  thing with substitution and element lowering.  I also toyed
  with making this a scalar type, which made it necessary in
  various places, although eventually I pulled back to the
  design where we always use packs as addresses.

- Pack boundaries are a core ABI concept, so the lowering has
  to wrap parameter pack expansions up as packs.  There are huge
  unimplemented holes here where the abstraction pattern will
  need to tell us how many elements to gather into the pack,
  but a naive approach is good enough to get things off the
  ground.

- Pack conventions are related to the existing parameter and
  result conventions, but they're different on enough grounds
  that they deserve to be separated.
2023-01-29 03:29:06 -05:00