- Calls to variadic-generic protocol requirements weren't applying
substitutions properly, so expansion-sensitive types in the callee
signature weren't pairing properly with their expansions in the
caller.
- emitPackTransform had an over-destroy if the transformation function
actually emitted into the temporary element directly.
- There were some MV ownership assertions that were wrong, which
revealed that the corresponding code really didn't handle consuming/
borrowing mismatches properly at all.
- We were completely mishandled consuming packs.
Fixes#81002, #80995, and #81600.
functions to compute them directly without a TypeLowering object, and
change a lot of getTypeLowering call sites to just use that.
There is one subtle change here that I think is okay: SILBuilder used to
use different TypeExpansionContexts when inserting into a global:
- getTypeLowering() always used a minimal context when inserting into
a global
- getTypeExpansionContext() always returned a maximal context for the
module scope
The latter seems more correct, as AFAIK global initializers are never
inlinable. If they are, we probably need to configure the builder with
an actual context properly rather than making global assumptions.
This is incremental progress towards computing this for most types
without a TypeLowering, and hopefully eventually removing TL entirely.
Specifically, we were not inserting the implicit isolated parameter and were not
setting up the actor prologue. To keep this specific to nonisolated(nonsending)
code, I only setup the actor prologue if we know that we have something that is
nonisolated(nonsending).
I also ported some async initializer tests to run with/without
nonisolated(nonsending) just to increase code coverage.
rdar://156919493
This was behind a feature flag. Unfortunately, this flag is viral, if
the module we consume and the consuming module had inconsistent settings
that could lead to deserialization errors. To avoid this, we need to
move this out of the flag and apply the attribute unconditionally. This
PR moves addressable-self out of the experimental flag and addresses a
couple of the fallouts:
* This attribute should not be applied to types with reference semantics
like foreign reference types or Obj-C classes.
* There was a SILGen assertion failure which is solved by pealing off
the @lvalue specifier from the type behind a load expression.
This fixes part of rdar://155971658
A call to a `@preconcurrency` function goes through a function conversion
that removes `Sendable` from existentials among other things. Implement
support for this by bitcasting indirect return slots whose type differs
from the formal indirect return type in concurrency markings only.
Fixes rdar://154240007
When accessing stored properties out of an addressable variable or parameter
binding, the stored property's address inside the addressable storage of the
aggregate is itself addressable. Also, if a computed property is implemented
using an addressor, treat that as a sign that the returned address should be
used as addressable storage as well. rdar://152280207
Specifically, I taught SILGen how to emit an AST like the following:
```
(force_value_expr implicit type="nonisolated(nonsending) (Date?) async -> Void" implicit_iuo_unwrap
(open_existential_expr implicit type="(nonisolated(nonsending) (Date?) async -> Void)?"
(opaque_value_expr implicit type="AnyObject")
(declref_expr type="AnyObject" decl="test.(file).repro().anyObject@test.swift:6:7" function_ref=unapplied)
(optional_evaluation_expr type="(nonisolated(nonsending) (Date?) async -> Void)?"
(inject_into_optional type="(nonisolated(nonsending) (Date?) async -> Void)?"
(function_conversion_expr type="nonisolated(nonsending) (Date?) async -> Void"
(bind_optional_expr type="(Date?) async -> Void" depth=0
(dynamic_member_ref_expr type="((Date?) async -> Void)?" decl="__ObjC.(file).Foo.start(at:)"
(opaque_value_expr type="AnyObject"))))))))
```
Since we are emitting an objc async function, there isn't an extra implicit
parameter like if we were using a swift async function. So, I just reused code
that was already used locally to look through these sorts of conversions. I
just had to add to that code support for conversions that add
nonisolated(nonsending). Previously it only supported looking through global
actor conversions.
rdar://152596823
This replaces the oddly-named mapIntoTypeExpansionContext() method
on SubstitutionMap itself in favor of a global function, just like
the ones that take Type and ProtocolConformanceRef.
This is an extension of a similar problem that I had fixed earlier where due to
the usage of intermediate Sendable types we do not propagate regions correctly.
The previous issue I fixed was that we were not properly tieing the result of a
foreign async completion handler to the block storage since we used an
intervening UnsafeContinuation (which is Sendable) to propagate the result into
the block storage. I fixed this by changing SILGen to insert a
merge_isolation_region that explicitly ties the result to the block storage.
This new issue is that the block that we create and then pass as the completion
handler is an @Sendable block. Thus when we call the actual objc_method, the
block storage and self are not viewed as being in the same region. In this PR, I
change it so that we add a merge_isolation_region from self onto the block
storage.
The end result of this is that we have that self, the result of the call, and
the block storage are all in the same region meaning that we properly diagnose
that returning an NSObject from the imported Objective-C function is task
isolated and thus we cannot return it as a sending result.
rdar://131422332
Don't bind references to storage to use (new ABI) coroutine accessors
unless they're guaranteed to be available. For example, when building
against a resilient module that has coroutine accessors, they can only
be used if the deployment target is >= the version of Swift that
includes the feature.
rdar://148783895
Now that coroutine kind (and consequently ABI) for the accessors is
keyed off a SIL option, it's no longer possible to read whether a given
SILFunction arose from a read/modify coroutine just by checking its
coroutine kind. Regardless of ABI, read/modify coroutines may only
unwind (i.e. are only permitted not to "run to completion") if the
relevant experimental (soon to be deleted) feature is enabled.
When a generic function has potentially Escapable outputs, those outputs
declare lifetime dependencies, which have no effect when substitution
leads to those types becoming `Escapable` in a concrete context.
This means that type substitution should canonically eliminate lifetime
dependencies targeting Escapable parameters or returns, and that
type checking should allow a function value with potentially-Escapable
lifetime dependencies to bind to a function type without those dependencies
when the target of the dependencies is Escapable.
Fixes rdar://147533059.
To ensure that dependent values have a persistent-enough memory representation
to point into, when an immutable binding is referenced as an addressable
argument to a call, have SILGen retroactively emit a stack allocation and
materialization that covers the binding's scope.
To ensure that dependent values have a persistent-enough memory representation
to point into, when an immutable binding is referenced as an addressable
argument to a call, have SILGen retroactively emit a stack allocation and
materialization that covers the binding's scope.
Without this, the borrow of the hop_to_executor lasts after the apply. Beyond
being unnecessary this results in an OSSA violation if we are passing an actor
as an isolated parameter to an initializer since we hop_to_executor the actor
and then pass it as a +1 parameter to the initializer causing the actor to be
consumed before its borrow ends.
rdar://144994837
In C++, we always expected to invoke the dtor for moved-from objects.
This is not the case for swift. Fortunately, @inCxx calling convention
is already expressing that the caller supposed to destroy the object.
This fixes the missing dtor calls when calling C++ functions taking
rvalue references. Fixes#77894.
rdar://140786022
The return pointer may point into the materialized base value, so if the base needs
materialization, ensure that materialization covers any futher projection of the
value.
Looking at the AST-level `getReadImpl` doesn't always correspond to what
accessor SILGen prefers to use, due to resilience, ABI rules, and other
concerns. In findStorageReferenceExprForMoveOnly, when determining whether
a storage reference is borrowable, use the same logic as SILGenLValue actually
uses to determine what storage or accessor access strategy to use.
Fixes rdar://142509673
This attribute makes it so that a parameter of the annotated type, as well as
any type structurally containing that type as a field, becomes passed as
if `@_addressable` if the return value of the function has a dependency on
the parameter. This allows nonescapable values to take interior pointers into
such types.
Right now it is basically a version of nonisolated beyond a few simple cases
like constructors/destructors where we are pretty sure we want to not support
this.
This is part of my bringup strategy for changing nonisolated/unspecified to be
caller isolation inheriting.
Fixes a correctness issue with unsafe addressors: `unsafeAddress` and
`unsafeMutableAddress`. Previously, the resulting `Unsafe[Mutable]Pointer` did
not depend on `self`, meaning that the compiler is allowed to destroy `self`
before any uses of the pointer. This happens to be valid for
`UnsafePointer.pointee` because, in that case, `self` does not have a lifetime
anyway; the correctness burden was on the programmer to use
`withExtendedLifetime` around all uses of `self`.
Now, unsafe addressors can be used for arbitrary `Self` types.
This also enables lifetime dependence diagnostics when the addressor points to a
`~Escapable` type.
Addressors can now be used as an implementation of borrowed properties.
Many APIs using nonescapable types would like to vend interior pointers to their
parameter bindings, but this isn't normally always possible because of representation
changes the caller may do around the call, such as moving the value in or out of memory,
bridging or reabstracting it, etc. `@_addressable` forces the corresponding parameter
to be passed indirectly in memory, in its maximally-abstracted representation.
[TODO] If return values have a lifetime dependency on this parameter, the caller must
keep this in-memory representation alive for the duration of the dependent value's
lifetime.
When the CoroutineAccessors feature is enabled, `begin_apply`
instructions produce an additional result representing the allocation
done by the callee. Fix a couple of cases where this additional result
was not being handled.
Instead of doing the pattern parsing in both the
C++ parser and ASTGen, factor out the parsing into
a request that returns the pattern to emit, regex
type, and version. This can then be lazily run
during type-checking.