Commit Graph

370 Commits

Author SHA1 Message Date
Erik Eckstein
369021f2b0 PerformanceDiagnostics: diagnose dynamic casts
Dynamic casts need metadata and therefore cannot be used in embedded swift.
Fixes an internal IRGen error.
2024-05-17 15:07:40 +02:00
Doug Gregor
c326fd3db2 Respect @preconcurrency for instance properties of non-sendable types in deinit
Instance properties of non-sendable types cannot safely be
accessed within deinitializers. Make sure we respect `@preconcurrency`
when diagnosing these.
2024-05-16 22:42:54 -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
f64f2529fb [region-isolation] Some more diagnostic wordsmithing.
rdar://127580781
2024-05-06 19:20:07 -07:00
Michael Gottesman
e4db879112 [region-isolation] Some more diagnostic wordsmithing.
rdar://127580781
2024-05-06 12:09:10 -07:00
Michael Gottesman
f02172a323 [region-isolation] Change terminology to use the term 'risk' instead of could. 2024-05-05 18:01:05 -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
699692bd39 [region-isolation] Change diagnostics from using the term transferring -> sending.
rdar://127580781
2024-05-05 18:00:54 -07:00
Joe Groff
cb5f1e20ae SILGen: Provide compatibility with prior BorrowingSwitch behavior.
To avoid breaking early adopters of this feature, accept attempts to `return`
a `let` binding in a noncopyable `switch` when it would be treated as a
borrow normally, with a warning that this behavior will change soon.
rdar://126775241
2024-04-19 15:20:31 -07:00
Michael Gottesman
a56d0f5ded [region-isolation] Tweak the main transferring diagnostic.
Specifically, I am transforming it from "may cause a race" -> "may cause a data
race". Adding data is a small thing, but it adds a bunch of nice clarity.
2024-04-06 22:50:26 -07:00
Anton Korobeynikov
c7a216058f [AutoDiff] First cut of coroutines differentiation (#71461)
This PR implements first set of changes required to support autodiff for coroutines. It mostly targeted to `_modify` accessors in standard library (and beyond), but overall implementation is quite generic.

There are some specifics of implementation and known limitations:
 - Only `@yield_once` coroutines are naturally supported
 - VJP is a coroutine itself: it yields the results *and* returns a pullback closure as a normal return. This allows us to capture values produced in resume part of a coroutine (this is required for defers and other cleanups / commits)
 - Pullback is a coroutine, we assume that coroutine cannot abort and therefore we execute the original coroutine in reverse from return via yield and then back to the entry
 - It seems there is no semantically sane way to support `_read` coroutines (as we will need to "accept" adjoints via yields), therefore only coroutines with inout yields are supported (`_modify` accessors). Pullbacks of such coroutines take adjoint buffer as input argument, yield this buffer (to accumulate adjoint values in the caller) and finally return the adjoints indirectly.
 - Coroutines (as opposed to normal functions) are not first-class values: there is no AST type for them, one cannot e.g. store them into tuples, etc. So, everywhere where AST type is required, we have to hack around.
 - As there is no AST type for coroutines, there is no way one could register custom derivative for coroutines. So far only compiler-produced derivatives are supported
 - There are lots of common things wrt normal function apply's, but still there are subtle but important differences. I tried to organize the code to enable code reuse, still it was not always possible, so some code duplication could be seen
 - The order of how pullback closures are produced in VJP is a bit different: for normal apply's VJP produces both value and pullback closure via a single nested VJP apply. This is not so anymore with coroutine VJP's: yielded values are produced at `begin_apply` site and pullback closure is available only from `end_apply`, so we need to track the order in which pullbacks are produced (and arrange consumption of the values accordingly – effectively delay them)
 - On the way some complementary changes were required in e.g. mangler / demangler

This patch covers the generation of derivatives up to SIL level, however, it is not enough as codegen of `partial_apply` of a coroutine is completely broken. The fix for this will be submitted separately as it is not directly autodiff-related.

---------

Co-authored-by: Andrew Savonichev <andrew.savonichev@gmail.com>
Co-authored-by: Richard Wei <rxwei@apple.com>
2024-04-04 17:24:55 -07:00
Michael Gottesman
19c72acff6 [silgen] Emit the location of the original function def if SILGen is erroring on a duplicate symbol definition.
This diagnostic is useful around silgen_name where it validates that we do not
have any weird collisions. Sadly, it just points where one of the conflicting
elements is... with this patch, we also emit an error on the other function if
we have a SILLocation.
2024-04-01 22:01:08 -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
Kuba (Brecka) Mracek
89cd62604b Merge pull request #72472 from kubamracek/embedded-keypaths
[embedded] Compile-time (literal) KeyPaths for Embedded Swift
2024-03-25 10:58:51 -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
2f9b519758 [region-isolation] Wordsmith "{access,use} here could race".
I am doing this since it isn't always going to be an access. We may not have
memory. We are talking about uses here!

I was able to just use sed so it was an easy fix.
2024-03-23 17:19:09 -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
Kuba Mracek
b642d771be [embedded] Compile-time (literal) KeyPaths for Embedded Swift
Enable KeyPath/AnyKeyPath/PartialKeyPath/WritableKeyPath in Embedded Swift, but
for compile-time use only:

- Add keypath optimizations into the mandatory optimizations pipeline
- Allow keypath optimizations to look through begin_borrow, to make them work
  even in OSSA.
- If a use of a KeyPath doesn't optimize away, diagnose in PerformanceDiagnostics
- Make UnsafePointer.pointer(to:) transparent to allow the keypath optimization
  to happen in the callers of UnsafePointer.pointer(to:).
2024-03-20 15:35:46 -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
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
Michael Gottesman
50712a1666 [region-isolation] Emit a standard short warning + long note when emitting a strongly transferring a structurally isolated value warning.
Specifically, instead of what I call an IsolationRegionInfo + Type error, e.x.:

> task-isolated value of type 'NonSendableType' passed as a strongly transferred parameter; later accesses could race

we use instead the standard warning of:

```swift
func transfer(_ x: transferring Type) {}

func test(_ x: Type) {
  transfer(x) // expected-warning {{transferring 'x' may cause a race}}
  // expected-note @-1 {{task-isolated 'x' is passed as a transferring parameter; Uses in callee may race with later task-isolated uses}}
}
```

Implementation wise, I left in the old type diagnostic as a backup for now. With
time, I am going to want to eliminate it completely.
2024-03-11 19:13:27 -07:00
Michael Gottesman
806cd7940e [region-isolation] Fix actor isolated parameters to get an actor isolated error instead of a task isolated error.
Now that we actually know the region that non transferrable things belong to, we
can use this information to give a better diagnostic here.

A really nice effect of this is that we now emit that actor isolated parameters
are actually actor isolated instead of task isolated.
2024-03-10 22:08:40 -07:00
Michael Gottesman
a5c8106e6a [region-isolation] Standardize on task-isolated instead of task isolated.
This matches actor-isolated as used in other parts of the compiler.
2024-03-10 22:08:40 -07:00
Michael Gottesman
6eb31b42b1 [region-isolation] Assigning into a transferring parameter should be a store, not a transfer.
rdar://123865943
2024-02-29 16:20:00 -08:00
Michael Gottesman
02be75a603 [region-isolation] Emit a better error when a function parameter is assigned into a different transferring parameter.
Just eliminating another "call site passes `self`" error.
2024-02-22 13:50:07 -08:00
Michael Gottesman
f296529ee0 [region-isolation] Change the main race error to be "transferring {could,may} cause a race"
As I was updating tests in the previous commit, I noticed that this would read better to me.
2024-02-22 13:50:06 -08:00
Michael Gottesman
1c193caedb [region-isolation] Eliminate more "call site passes self" warnings
I just did a full pass through. There were some cases around nonisolated
closures defined in methods and global actor isolated things where we are now
emitting the wrong message. I am going to fix that in subsequent commits.
2024-02-22 13:50:06 -08:00
Michael Gottesman
7fe100a762 [region-isolation] Clean up the named value transfer warning. 2024-02-22 13:50:06 -08:00
John McCall
868fc6ad46 Basic SILGen for @isolated(any).
The main piece that's still missing here is support for closures;
they actually mostly work, but they infer the wrong isolation for
actor-isolated closures (it's not expressed in the type, so obviously
they're non-isolated), so it's not really functional.  We also have
a significant problem where reabstraction thunks collide incorrectly
because we don't mangle (or represent!) formal isolation into
SILFunctionType; that's another follow-up.  Otherwise, I think SILGen
is working.
2024-02-19 21:21:03 -05:00
nate-chandler
905a655fe8 Merge pull request #71670 from nate-chandler/partial-consumption/20240215/1/imported-types
[MoveChecker] Ban exported partial consumption.
2024-02-15 21:44:32 -08:00
Nate Chandler
da968dbd58 [MoveChecker] Ban exported partial consumption.
To avoid dialecticization based on compilation mode, ban for
non-resilient modules partial consumption of aggregates which would be
illegal were those modules instead resilient.
2024-02-15 16:25:53 -08:00
eeckstein
2294d9f170 Merge pull request #71650 from eeckstein/deinit-perf-error
PerformanceDiagnostics: print an error in embedded swift if a value type deinit cannot be devirtualized
2024-02-15 21:25:43 +01:00
Erik Eckstein
171cca4ec7 PerformanceDiagnostics: print an error in embedded swift if a value type deinit cannot be devirtualized
Not de-virtualized value type deinits can require metatype in case the deinit needs to be called via the value witness table.
Usually this does not happen because deinits are mandatory de-virtualized. But it can show up if e.g. wrong build options are used.

rdar://122651706
2024-02-15 14:01:45 +01:00
Erik Eckstein
232a244a60 Deserializer: better error message if types of referenced functions don't match
So far this resulted in an assert (in best case). Now a readable error is printed.
2024-02-15 10:14:35 +01:00
Pavel Yaskevich
1e1564e4c9 Merge pull request #70555 from xedin/issue-70550
[Concurrency] `memberAccessHasSpecialPermissionInSwift5` should treat…
2024-02-13 09:52:49 -08:00
John McCall
d5142668f4 SIL and IRGen support for @isolated(any). SILGen to come. 2024-02-13 03:04:13 -05:00
Andrew Trick
274c47877f LifetimeDepenenceDiagnostics improvements
Better handling of @_unsafeNonescapableResult

Improve diagnostic clarity.
2024-02-12 09:57:14 -08:00
Pavel Yaskevich
4275bbd632 [SILOptimizer] FlowIsolation: Teach analysis to recognize use of init accessor properties
Init accessor properties should be handled specifically because
they do not reference underlying storage directly via `ref_element_addr`
instructions when 'self' is fully initialized.
2024-02-07 09:30:41 -08:00
Michael Gottesman
f87dbb5181 [region-isolation] Eliminate term "binding" from diagnostic. 2024-02-06 16:18:43 -08:00
Michael Gottesman
fef1b5e3df [region-isolation] Use VariableNameUtils to emit name diagnostics when possible.
A name diagnostic looks as follows:

Some notes:

1. VariableNameUtils still doesn't pattern match all cases. In the cases where
we fail to pattern match, I fall back to the old diagnostics. I am going to be
adding tests/etc specific to VariableNameUtils in a later patch.

2. I took this as an opportunity to begin preparing to change the diagnostics
into diags of the following form:

a. The main diagnostic is changed to something short "transferring non-Sendable
%0 could yield races with later accesses".

b. I added a longer note at the same location that explains that our caller is
in a specific isolation domain and our callee is isolated differently.

c. I added a note on the definition location of the identified value.
2024-02-06 13:42:35 -08:00
Andrew Trick
ddceffaf3b LifetimeDependenceDiagnostics pass
Initial diagnostic pass to enforce ~Escapable types.
2024-01-30 11:45:55 -08:00
nate-chandler
f2d68a21dc Merge pull request #71162 from nate-chandler/partial-consumption/20240125/1/scope-end-diagnostic
[MoveChecker] Distinguished scope end diagnostics.
2024-01-29 18:27:10 -08:00
Nate Chandler
5441ff1d97 [MoveChecker] Distinguished scope end diagnostics.
There are several kinds of scopes at which it is required that an
address be initialized:
(1) the whole function -- for inout argument to the function
(2) the region a coroutine is active -- for an inout yielded by a
    coroutine into the function
(3) the region of a memory access -- for a `begin_access [modify]`.

The move checker enforces that they are initialized at that point by
adding instructions at which the field must be live to liveness.

Previously, all such scopes used the end of the function as the point at
which the memory had to have been reinitialized.  Here, the relevant end
of scope markers are used instead.

More importantly, here the diagnostic is made to vary--the diagnostic,
that is, that is issued in the face an address not being initialized at
the end of these different kind of scopes.
2024-01-29 11:49:30 -08:00
Michael Gottesman
9ff4094b5d [region-isolation] Handle non-transferrable function arguments via an explicitly transferred parameter.
I also while doing this I replaced a bunch of places where we used to crash due
to invariants failing to instead emit a "I don't know error" since it is more
actionable for the user.
2024-01-27 16:16:33 -08:00
Michael Gottesman
d77dede6ce [region-isolation] Change WARNINGS to be ERRORs that are limited as warnings until swift 6.
I added some small infrastructure so that the default way one creates
diagnostics sets this automagically so mistakes cannot result.

rdar://121755281
2024-01-27 16:16:33 -08:00
Michael Gottesman
f077e4a9d7 [region-isolation] Fix the call site or self error for values used in the same region as a function argument.
This is just good to do and also makes it so that in my test case for
assumeIsolated, I get a better msg.
2024-01-25 20:40:56 -08:00
Michael Gottesman
7c79a24a1f [region-isolation] Values that are captured by an actor isolated closures are transferred to that closure.
This commit makes it so that we treat values captured by an actor isolated
closure as being transferred to that closure. I also introduced a new diagnostic
for these warnings that puts the main warning on the capture point of the value
so the user is able to see the actual capture that causes the transfer to occur:

```swift
  nonisolated func testLocal2() async {
    let l = NonSendableKlass()

    // This is not safe since we use l later.
    self.assumeIsolated { isolatedSelf in
      isolatedSelf.ns = l
    }

    useValue(l) // expected-note {{access here could race}}
  }
```

```
test.swift:74:14: warning: main actor-isolated closure captures value of non-Sendable type 'NonSendableKlass' from nonisolated context; later accesses to value could race
    useValue(x) // expected-warning {{main actor-isolated closure captures value of non-Sendable type 'NonSendableKlass' from nonisolated context; later accesses to value could race}}
             ^
test.swift:76:12: note: access here could race
  useValue(x) // expected-note {{access here could race}}
           ^
```

One thing to keep in mind is that if we have a function argument being captured
in this way, we still emit the "call site passes `self`" error. I am going to
begin cleaning that up in the next commit in this PR so that we emit a better
error here. But it makes sense to split these into two separate commits since
they are doing different things.

rdar://121345525
2024-01-25 20:40:56 -08:00