Commit Graph

149 Commits

Author SHA1 Message Date
Michael Gottesman
7255281c1d [region-isolation] Use a hard to use API correctly.
Specifically, this API has some hard edges where instead of just returning an
invalid value to signal that we do not have self, we assert or return something
bogus. This commit just fixes our usage of that API to be correct.

rdar://132545626
2024-07-31 16:51:15 -07:00
Michael Gottesman
bcbf5c515e [region-isolation] Emit an error when we assign a non-disconnected value into a sending result.
rdar://127318392
2024-07-18 21:29:08 -07:00
Michael Gottesman
ace94b00ba [region-isolation] Move RepresentativeValue from RegionAnalysis.h -> PartitionUtils.h and add APIs for mapping an ElementID -> Representative.
This is just moving up the declaration in the chain of dependencies so that I
can write logic in PartitionUtils.h using it. I also added entrypoints to lookup
the ReprensetativeValue for our various emitters.
2024-07-18 21:28:22 -07:00
Michael Gottesman
219073be97 Revert "[region-isolation] Make "unknown pattern error" always an error."
This reverts commit b63781f7ba.

We found some cases where due to malformed IR that we allow through due to
either us compiling for strict-concurrency=complete+swift-5 or swift-6 +
preconcurrency, that we can actually have actor isolation mismatch. I am going
to in a subsequent commit add a better phrasing here. But for now, just undo the
conversion from error -> warning.

rdar://131757602
2024-07-17 16:09:55 -07:00
Michael Gottesman
b63781f7ba [region-isolation] Make "unknown pattern error" always an error.
This shows an actual issue with the compiler where semantically we should crash.
Rather than crashing (due to the broken invariants), we emit this error so that
the user gets a nice error message at the problem place and can work around it
instead of just getting a mysterious crash.

Previously, we were making this a warning in swift 5 mode... but given the
issues, it makes sense to emit an error diagnostic so we get the feedback and
the user cannot ship the code.

rdar://131482934
2024-07-10 12:48:09 -07:00
Michael Gottesman
03b26fd65b [region-isolation] Treat async let as a isolation inference boundary closure and fix diagnostics due to change.
Otherwise, we will assume that an async let autoclosure infers isolation from
its DeclContext... which we do not want. An async let autoclosure should always
be nonisolated + sending.

The diagnostic change that I mentioned in the header is that we were emitting
unfortunate "sending task or actor isolated could result in races" error. I
eliminated this by adding a new diagnostic for transfer non transferrable errors
happening in autoclosures. So now we emit this:

```swift
  func asyncLetInferAsNonIsolated<T : Actor>(
    isolation actor: isolated T
  ) async throws {
    async let subTask: Void = {
      await useValueAsyncNoReturnWithInstance(self, actor)
      // expected-warning @-1:47 {{sending 'self' risks causing data races}}
      // expected-note @-2 {{sending 'actor'-isolated 'self' into async let risks causing data races between nonisolated and 'actor'-isolated uses}}
    }()
    await subTask
```

I also noticed that we did not have enough test cases for autoclosures in
general so I also added a bunch of tests just so we can see what the current
behavior is. I think there are a few issues therein (I believe some may have
been reported due to '??').

rdar://130151318
2024-07-08 11:22:29 -07:00
Michael Gottesman
57392b1031 [region-isolation] Fix a nullptr error.
This is triggered by the test case in the next commit. The problem is anonymous
closures can be passed here and they do not have a ValueDecl so there isn't a
decl for us to use.
2024-07-08 11:19:20 -07:00
Michael Gottesman
8770e90e43 Fix a thinko.
I was working on c20abe570d and
03bfadea60 at the same time and I forgot to update
to use the new API in 03bfadea60 before I commited
c20abe570d. Sorry!
2024-07-02 21:00:59 -07:00
Michael Gottesman
c20abe570d Merge pull request #74919 from gottesmm/pr-d8b24a45ff257893c8172491f11a617fc00d5589
[region-isolation] Implement support for 'inout sending' diagnostics.
2024-07-02 20:16:25 -07:00
Michael Gottesman
6fe749626f [region-isolation] Add 'inout sending' diagnostics.
Specifically:

1. We error now if one transfers an 'inout sending' parameter and does not
reinitialize it before the end of the function.

2. We error now if one merges an 'inout sending' parameter into an actor
isolated region and do not reinitialize it with a non-actor isolated value
before the end of the function.

rdar://126303739
2024-07-02 16:21:44 -07:00
Michael Gottesman
5d4b93fa5d [region-isolation] Add a wrapper ADT for RequireInst SILInstructions so we can attach a Kind and propagate it.
The reason why I am doing this is that I am adding support for failing to
reinitialize an inout sending parameter that was transferred. To make it really
easy to do I am just going to explicitly represent this on the RequireInst and
let the decision on what diagnostic to be done to be represented in the
pseudo-IR instead of trying to just infer it straight from the type of require
inst. This keeps all of the logic in the same place and attempts to keep the
diagnostic emitter not use logic and instead just emit.

This is NFC so I can make sure that things work before adding the additional code.
2024-07-02 16:21:44 -07:00
Michael Gottesman
e9e5c4eb4c [region-isolation] Ensure that some NDEBUG code is properly guarded. 2024-07-02 13:55:33 -07:00
Michael Gottesman
02e003f0de [region-isolation] Change capturing a value into an async let that is not further sent into an actor isolated function to use a new style error.
Just going through and fixing sending errors.

rdar://130915737
2024-07-01 13:12:36 -07:00
Michael Gottesman
78d74cf716 [region-isolation] Make sil-region-isolation-assert-on-unknown-pattern also work with TransferNonSendable versions of the error.
This asserts only option is an option to make it quicker/easier to triage
unknown pattern match errors by aborting when we emit it (allowing one to
immediately drop into the debugger at that point).

Previously, it only happened for errors in RegionAnalysis not in
TransferNonSendable itself.
2024-07-01 13:12:36 -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
Michael Gottesman
1bef011e48 [region-isolation] Add the ability for the analysis to emit "unknown error" partition ops in case we detect a case we cannot pattern match.
DISCUSSION: The analysis itself is unable to emit errors. So we achieve the same
functionality by in such cases emitting a partition op that signals to our user
that when they process that partition op they should emit an "unknown pattern"
error at the partition op's instructions.

I have wanted this for a long time, but I never got around to it.
2024-05-27 21:42:04 -07:00
Michael Gottesman
741244e16b [region-isolation] Split in the type system SILIsolationInfo that has been merged and those that haven't.
Specifically, I introduced a new composition type called
SILDynamicMergedIsolationInfo that just contains a
SILIsolationInfo. Importantly, whenever one merges a SILIsolationInfo with
another SILIsolationInfo, one gets back a SILDynamicMergedIsolationInfo.

The reason why I am doing this is that we drop nonisolated(unsafe) when merging
so I want to ensure that parts of the code that use merging (where the dropping
occurs) and normal SILIsolationInfo where we do not want to merge is
distinguished.
2024-05-27 21:41:54 -07:00
Michael Gottesman
3a1f58a72a [region-isolation] Make sure that nonisolated(unsafe) works in all cases.
I made sure we match what we get without region isolation by turning off region
isolation in one of the test runs on the test for this.

There is one problem where for non-final classes with nonisolated(unsafe) var
fields, we currently do not properly squelch since I need to do more
infrastructure work. I am going to do that in the next commit.

rdar://128299305
2024-05-27 21:41:32 -07:00
Doug Gregor
6f969be881 Merge pull request #73738 from DougGregor/more-preconcurrency-fixes
More preconcurrency fixes
2024-05-19 18:30:05 -07:00
Doug Gregor
e4dac750dc Unify two implementations of "concurrency diagnostic behavior limit"
The "send non-Sendable" pass had a copy of the code for determining
what limit to put on the diagnostic behavior for a given reference to
a nominal type declaration. Rather than update that copy for the
recent changes to the canonical version of this in the type checker,
share the computation.
2024-05-19 13:22:31 -07:00
Michael Gottesman
71e95b9527 [sending] Change transferring diagnostics to say sending instead of transferring.
Just trying to slice off a larger change where I change these tests to actually
use 'sending'. This is nice to do now since it is algebraic to do.

rdar://128216574
2024-05-16 20:35:34 -07:00
Michael Gottesman
e3e78ad6bb [sending] Change the internals of sending to be based around 'sending' instead of 'transferring'.
We still only parse transferring... but this sets us up for adding the new
'sending' syntax by first validating that this internal change does not mess up
the current transferring impl since we want both to keep working for now.

rdar://128216574
2024-05-16 12:20:45 -07:00
Michael Gottesman
50c2d678f2 [region-isolation] When inferring isolation for an argument, handle non-self isolated parameters as well as self parameters that are actor isolated.
As part of this I went through how we handled inference and rather than using a
grab-bag getActorIsolation that was confusing to use, I created split APIs for
specific use cases (actor instance, global actor, just an apply expr crossing)
that makes it clearer inside the SILIsolationInfo::get* APIs what we are
actually trying to model. I found a few issues as a result and fixed most of
them if they were small. I also fixed one bigger one around computed property
initializers in the next commit. There is a larger change I didn't fix around allowing function
ref/partial_apply with isolated self parameters have a delayed flow sensitive
actor isolation... this will be fixed in a subsequent commit.

This also fixes a bunch of cases where we were printing actor-isolated instead
of 'self' isolated.

rdar://127295657
2024-05-10 15:33:44 -07:00
Michael Gottesman
787bb7d249 [region-isolation] Create a non-"callee" kind of error for async let.
I am doing this separately from the previous fix for just normal region
isolation since without transferring args and results enabled, we do not hit
this code path. But since I am here, I want to fix it at the same time.

rdar://127588005
2024-05-05 22:39:59 -07:00
Michael Gottesman
58fd432e6c Remove clang optimize off and loosen an error in the swift-version test. 2024-05-05 19:33:11 -07:00
Michael Gottesman
a933c14b77 [region-isolation] Only print the type of region that a value is in if it is not disconnected.
Just another diagnostic tweak.
2024-05-05 18:01:05 -07:00
Michael Gottesman
0b761109e2 [region-isolation] If we can infer the callee's name, use that instead of just saying 'callee'.
I also wordsmithed the error message to use the term 'risk' instead of less
negative terms.
2024-05-05 18:01:05 -07:00
Michael Gottesman
9ce43d5a98 [region-isolation] Suppress non-Sendable region isolation errors appropriately when the type is imported by using @preconcurrency import.
This translates the rules for @preconcurrency import from SE-0337 into the
region isolation world. Specifically if a module is compiled without strict
concurrency checking and imported with @preconcurrency:

1. All types from that module that are implicitly non-Sendable have diagnostics
suppressed in swift 5 and swift 6.

2. All types from that module that are explicitly non-Sendable emit warnings in
both swift 5 and swift 6.

rdar://126804052
2024-04-23 22:26:07 -05:00
Michael Gottesman
51ef67d7df [variable-name-utils] Refactor inferName/inferNameAndRoot helpers onto VariableNameInferrer.
I have been using these in TransferNonSendable and they are useful in terms of
reducing the amount of code that one has to type to use this API. I am going to
need to use it in SILIsolationInfo, so it makes sense to move it into
SILOptimizer/Utils.

NFCI.
2024-04-11 15:41:18 -07:00
Michael Gottesman
c9fe8ff935 [region-isolation] Eliminate unnecessary using TrackableValueID = Element.
Having two artificial typedefs for the same wrapped value is just confusing.
Better to just have one and make the code simpler to understand.
2024-04-11 15:41:18 -07:00
Michael Gottesman
ca8179aa7c [region-isolation] Track operand info in a separate map rather than inline in a TransferringOperand data structure.
This is backing out an approach that I thought would be superior, but ended up
causing problems.

Originally, we mapped a region number to an immutable pointer set containing
Operand * where the region was tranferred. This worked great for a time... until
I began to need to propagate other information from the transferring code in the
analysis to the actual diagnostic emitter.

To be able to do that, my thought was to make a wrapper type around Operand
called TransferringOperand that contained the operand and the other information
I needed. This seemed to provide me what I wanted but I later found that since
the immutable pointer set was tracking TransferringOperands which were always
newly wrapped with an Operand *, we actually always created new pointer
sets. This is of course wasteful from a memory perspective, but also prevents me
from tracking transferring operand sets during the dataflow since we would never
converge.

In this commit, I fix that issue by again tracking just an Operand * in the
TransferringOperandSet and instead map each operand to a state structure which
we merge dataflow state into whenever we visit it. This provides us with
everything we need to in the next commit to including a region -> transferring
operand set equality check in our dataflow equations and always converge.
2024-04-10 10:30:10 -07:00
Michael Gottesman
1cf4e99454 Propagate global actor-ness of functions/closures.
I fixed a bunch of small issues around here that resulted in a bunch of radars
being fixed. Specifically:

1. I made it so that we treat function_refs that are from an actor isolated
function as actor isolated instead of sendable.

2. I made it so that autoclosures which return global actor isolated functions
are treated as producing a global actor isolated function.

3. I made it so that we properly handle SILGen code patterns produced by
Sendable GlobalActor isolated things.

rdar://125452372
rdar://121954871
rdar://121955895
rdar://122692698
2024-03-29 14:39:34 -07:00
Michael Gottesman
d0d2f2d9b2 [region-isolation] Change the transfer non-transferrable value due to capture by an isolated closure diagnostic to be a named diagnostic.
rdar://125372790
2024-03-25 20:17:26 -07:00
Michael Gottesman
5e58aa64a2 [region-isolation] When emitting an error for an isolated closure use of a never transferrable value, use the dynamic isolation. Do not assume it is task isolated.
rdar://125372336
2024-03-25 20:17:26 -07:00
Michael Gottesman
7cda418d45 [region-isolation] Convert the isolation having autoclosure expr error to use a named variant.
It was pretty easy to do since I already have the name from the AST.
2024-03-23 21:17:41 -07:00
Michael Gottesman
7d07fb5a11 [region-isolation] Add a named variant of the transfer via closure capture diagnostic.
Just converting another diagnostic to its final named form.
2024-03-23 21:17:41 -07:00
Michael Gottesman
5580bb4ba7 [region-isolation] Add a named variant of the use after pass via strongly transfering parameter.
Specifically, I added a named version of the diagnostic:

 func testSimpleTransferLet() {
   let k = Klass()
-  transferArg(k) // expected-warning {{binding of non-Sendable type 'Klass' accessed after being transferred; later accesses could race}}
+  transferArg(k) // expected-warning {{transferring 'k' may cause a race}}
+  // expected-note @-1 {{'k' used after being passed as a transferring parameter}}
   useValue(k) // expected-note {{use here could race}}
 }

and I also cleaned up the typed version of the diagnostic that is used
if we fail to find a name:

 func testSimpleTransferLet() {
   let k = Klass()
-  transferArg(k) // expected-warning {{binding of non-Sendable type 'Klass' accessed after being transferred; later accesses could race}}
-  transferArg(k) // expected-warning {{value of non-Sendable type 'Klass' accessed after being transferred; later accesses could race}}
   useValue(k) // expected-note {{use here could race}}
 }

This is the 2nd to the last part of a larger effort to rework all of
the region based diagnostics to first try and use names and only go back
to the old typed diagnostics when we fail to look up a name (which should
be pretty rare, but is always possible).

At some point if I really feel confident enough with the name lookup code, I am
most likely just going to get rid of the typed diagnostic code and just emit a
compiler doesnt understand error. The user will still not be able to ship the
code but would also be told to file a bug so that we can fix the name
inference.
2024-03-23 21:17:41 -07:00
Michael Gottesman
357a53ab48 [region-isolation] Clean up use after transfer error to use the dynamic isolation information of the transfered operand value in its diagnostic message.
As an example of the change:

-  // expected-note @-1 {{'x' is transferred from nonisolated caller to main actor-isolated callee. Later uses in caller could race with potential uses in callee}}
+  // expected-note @-1 {{transferring disconnected 'x' to main actor-isolated callee could cause races in between callee main actor-isolated and local nonisolated uses}}

Part of the reason I am doing this is that I am going to be ensuring that we
handle a bunch more cases and I wanted to fix this diagnostic before I added
more incaranations of it to the tests.
2024-03-22 13:12:51 -07:00
Michael Gottesman
5b8171240d [region-isolation] Rename IsolationRegionInfo -> SILIsolationInfo.
That is really what IsolationRegionInfo is.
2024-03-21 14:16:20 -07:00
Michael Gottesman
e0fdce1fa3 [region-isolation] Convert TransferringOperand to be a bump allocated ptr type from a pointer type.
I need to start tracking the dynamic IsolationRegionInfo for the transferring
operand so I can ignore uses that are part of the same
IsolationRegionInfo. IsolationRegionInfo doesn't fit into a pointer, so just to
keep things the same, I am going to just allocate it.

This is an initial staging commit that tests out the bump ptr allocating without
expanding the type yet.
2024-03-21 14:16:20 -07:00
Michael Gottesman
7368de2a20 [region-isolation] Remove variable_defined_here from named use after transfer error.
This is just a pseudo-why are these two things part of the same region error. I
am going to remove this for now and the proper form of this diagnostic will come
back when I land the region history functionality.
2024-03-19 13:19:08 -07:00
Michael Gottesman
f796f11c97 [region-isolation] Rename ValueIsolationRegionInfo -> IsolationRegionInfo. 2024-03-18 12:24:34 -07:00
Michael Gottesman
afbcf85727 [region-isolation] Change named transfer non transferable error to use the dynamic merged IsolationRegionInfo found during dataflow.
I also eliminated the very basic "why is this task isolated" part of the warning
in favor of the larger, better, region history impl that I am going to land
soon. The diagnostic wasn't that good in the first place and also was fiddly. So
I removed it for now.

rdar://124960994
2024-03-18 12:13:36 -07:00
Michael Gottesman
f7d1f2acb9 [region-isolation] Define getIsolationRegionInfo(Element elt) on PartitionOpEvaluator.
This will let me look up the dynamic isolation region associated with \p elt
while performing dataflow.
2024-03-18 12:13:30 -07:00
Michael Gottesman
465bb230c4 [region-isolation] Rename callback handleFailure -> handleLocalUseAfterTransfer.
Now that we have other forms of error callbacks, having such a general name for
any specific failure is misleading and hinds intent.
2024-03-18 12:13:30 -07:00
Michael Gottesman
acca7353db [transferring] Make async let take a transferring result if its result is non-Sendable.
Some notes:

1. If the result is non-Sendable and we didn't infer something that is
transferring, we still emit the current sema error that says that one cannot
assign a non-Sendable value to an async let.

2. When region isolation is enabled, but transferring args and results are
disabled, we leave the async let semantics alone. This means that the async let
closure is still @Sendable and one cannot pass in non-Sendable values to it.
2024-03-13 15:30:54 -07:00
Michael Gottesman
d72f267538 Merge pull request #72271 from gottesmm/pr-e9ccc43526e04bf00a21d49893c15ef4031898e8
[region-isolation] When inferring AST arg nums from SIL operand numbers, ignoring indirect operands.
2024-03-12 18:26:12 -07:00
Michael Gottesman
4422eb5d56 [region-isolation] When inferring AST arg nums from SIL operand numbers, ignoring indirect operands.
Otherwise, we get off by one errors.

NOTE: I removed the assert that this originally hit since it is possible for us
to perhaps hit other issues and it would be better to just emit a suboptimal
error than crashing. With time, I will probably make it so if we miss we emit a
"compiler couldn't understand error".

rdar://124478890
2024-03-12 14:36:26 -07:00
Michael Gottesman
2ee1242304 [region-isolation] Give a proper named error for passing a never transferring values as a transferring argument
This eliminates a bunch of "task or actor isolated value transferred".

I also deleted some dead code.
2024-03-12 12:26:55 -07:00
Michael Gottesman
aa9a2f6691 [region-isolation] Clean up the call passes self error to be the shorter "task or actor isolated value cannot be transferred".
We do not emit these very much anymore. I am just keeping it in place a bit
longer... eventually, this should just be an unknown pattern error since if a
user sees this it won't compile and we would rather then send it to us so we can
fix it.
2024-03-11 19:13:27 -07:00