If a guaranteed value is used in a dead-end exit block and the enclosing value is _not_ destroyed in this block, we end up missing the enclosing value as phi-argument after duplicating the loop.
TODO: once we have complete lifetimes we can remove this check again.
rdar://159125605
This makes the code easier to write and also prevents any lifetime issues from a
diagnostic outliving the SmallString due to diagnostic transactions.
(cherry picked from commit 010fa39f31)
Specifically in terms of printing, if NonisolatedNonsendingByDefault is enabled,
we print out things as nonisolated/task-isolated and @concurrent/@concurrent
task-isolated. If said feature is disabled, we print out things as
nonisolated(nonsending)/nonisolated(nonsending) task-isolated and
nonisolated/task-isolated. This ensures in the default case, diagnostics do not
change and we always print out things to match the expected meaning of
nonisolated depending on the mode.
I also updated the tests as appropriate/added some more tests/added to the
SendNonSendable education notes information about this.
(cherry picked from commit 14634b6847)
I am doing this so that I can change how we emit the diagnostics just for
SendNonSendable depending on if NonisolatedNonsendingByDefault is enabled
without touching the rest of the compiler.
This does not actually change any of the actual output though.
(cherry picked from commit 4ce4fc4f95)
We were effectively working around this previously at the SIL level. This caused
us not to obey the semantics of the actual evolution proposal. As an example of
this, in the following, x should not be considered main actor isolated:
```swift
nonisolated(nonsending) func useValue<T>(_ t: T) async {}
@MainActor func test() async {
let x = NS()
await useValue(x)
print(x)
}
```
we should just consider this to be a merge and since useValue does not have any
MainActor isolated parameters, x should not be main actor isolated and we should
not emit an error here.
I also fixed a separate issue where we were allowing for parameters of
nonisolated(nonsending) functions to be passed to @concurrent functions. We
cannot allow for this to happen since the nonisolated(nonsending) parameters
/could/ be actor isolated. Of course, we have lost that static information at
this point so we cannot allow for it. Given that we have the actual dynamic
actor isolation information, we could dynamically allow for the parameters to be
passed... but that is something that is speculative and is definitely outside of
the scope of this patch.
rdar://154139237
(cherry picked from commit c12c99fb73)
Centralize the logic for figuring out the conformances for the various
init_existential* instructions in a SILIsolationInfo static method, and
always go through that when handling "assign" semantics. This way, we
can use CONSTANT_TRANSLATION again for these instructions, or a simpler
decision process between Assign and LookThrough.
The actually undoes a small change made earlier when we stopped looking
through `init_existential_value` instructions. Now we do when there are
no isolated conformances.
Better match the style of SILIsolationInfo by moving the code for determining
SILIsolationInfo from conformances or dynamic casts to existentials into
static `getXYZ` methods on SILIsolationInfo.
Other than adding an assertion regarding disconnected regions, no
intended functionality change.
When we introduce isolation due to a (potential) isolated conformance,
keep track of the protocol to which the conformance could be
introduced. Use this information for two reasons:
1. Downgrade the error to a warning in Swift < 7, because we are newly
diagnosing these
2. Add a note indicating where the isolated conformance could be introduced.
(cherry picked from commit 02c34bb830)
This results in wrong argument/return calling conventions.
First, the method call must be specialized. Only then the call can be de-virtualized.
Usually, it's done in this order anyway, because the `class_method` instruction is located before the `apply`.
But when inlining functions, the order (in the worklist) can be the other way round.
Fixes a compiler crash.
rdar://154631438
OSSA lifetime canonicalization can take a very long time in certain
cases in which there are large basic blocks. to mitigate this, add logic
to skip walking the liveness boundary for extending liveness to dead
ends when there aren't any dead ends in the function.
Updates `DeadEndBlocks` with a new `isEmpty` method and cache to
determine if there are any dead-end blocks in a given function.
(cherry picked from commit 1f3f830fc7)
In this case, what is happening is that in SILGen, we insert implicit
DistributedActor.asLocalActor calls to convert a distributed actor to its local
any Actor typed form. The intention is that the actor parameter and result are
considered the same... but there is nothing at the SIL level to enforce that. In
this commit, I change ActorInstance (the utility that defines actor identity at
a value level) to look through such a call.
I implemented this by just recognizing the decl directly. We already do this in
parts of SILGen, so I don't really see a problem with doing this. It also
provides a nice benefit that we do not have to modify SILFunctionType to
represent this or put a @_semantic attribute on the getter.
NOTE: Generally, Sema prevents us from mixing together different actors. In this
case, Sema does not help us since this call is inserted implicitly by the
distributed actor implementation in SILGen. So this is not a problem in general.
rdar://152436817
(cherry picked from commit 331626e6fa)
Currently we delete dead drop_deinit instructions in InstructionDeleter. For address results, we may end up with ownership errors after being promoted to value forms. For value results, fixLifetimes mode of InstructionDeleter will insert an illegal destroy_value
rdar://151104993
In language 6 mode keypath instructions are created as existentials and the optimizer needs to look through the `open_existential_ref` instructions to recognize a keypath.
rdar://150173106
When the utility is used by the ConsumeOperatorCopyableValuesChecker,
the checker guarantees that the lifetime can end at the consumes, that
there are no uses after those consumes. In that circumstance, the
utility maintains liveness to those consumes and as far as possible
without introducing a copy everywhere else.
The lack of complete lifetimes has forced the utility to extend liveness
of values to dead-ends. That extension, however, is in tension with the
use that the checker is putting the utility to. If there is a dead-end
after a consume, liveness must not be maintained to that dead-end.
rdar://147586673
Otherwise, we can be inconsistent with isolations returned by other parts of the
code. Previously we were just treating it always as self + nom decl, which is
clearly wrong if a type is not self (e.x.: if it is an isolated parameter).
rdar://135459885
(cherry picked from commit 0ece31e4f6)
Specifically, we only do this if the base is a let or if it is a var but not
captured by reference.
rdar://149019222
(cherry picked from commit 23b6937cbc)
I am doing this so I can mark requires as being on a mutable non-Sendable base
from a Sendable value.
I also took this as an opportunity to compress the size of PartitionOp to be 24
bytes instead of 40 bytes.
(cherry picked from commit a045c9880a)
Addressable parameters must remain indirect.
Incidentally also fixes an obvious latent bug in which all specialization was
disabled if any metatypes could not be specialized.
Fixes rdar://145687827 (Crash of inline-stored Span properties with optimizations)
(cherry picked from commit 935b5e7ea2)
* `sitofp` signed integer to floating point
* `rint` round floating point to integral
* `bitcast` between integer and floating point
Constant folding `bitcast`s also made it necessary to rewrite constant folding for Nan and inf values, because the old code explicitly checked for `bitcast` intrinsics.
Relying on constant folded `bitcast`s makes the new version much simpler.
It is important to constant fold these intrinsics already in SIL because it enables other optimizations.
This is a narrow fix, we are going to work on fixing this properly
and allowing both devirtualization and specialization for distributed
requirement witnesses.
Anything that uses an ad-hoc serialization requirement scheme cannot
be devirtualized because that would result in loss of ad-hoc conformance
in new substitution map.
Resolves: https://github.com/swiftlang/swift/issues/79318
Resolves: rdar://146101172
When performing a dynamic cast to an existential type that satisfies
(Metatype)Sendable, it is unsafe to allow isolated conformances of any
kind to satisfy protocol requirements for the existential. Identify
these cases and mark the corresponding cast instructions with a new flag,
`[prohibit_isolated_conformances]` that will be used to indicate to the
runtime that isolated conformances need to be rejected.
The body of a function has to be re-analyzed for every call
site of the function, which is very expensive and if the
body is not changed would produce the same result.
This takes about ~10% from swift-syntax overall build time
in release configuration.
We need to consider that archetypes (generic types) can be existentials if they conform to self-conforming protocols.
Fixes a miscompile
rdar://147269904