Add TermInst::forwardedOperand.
Add SILArgument::forwardedTerminatorResultOperand. This API will be
moved into a proper TerminatorResult abstraction.
Remove getSingleTerminatorOperand, which could be misused because it's
not necessarilly forwarding ownership.
Remove the isTransformationTerminator API, which is not useful or well
defined.
Rewrite several instances of complex logic to handle block arguments
with the simple terminator result API. This defines away potential
bugs where we don't detect casts that perform implicit conversion.
Replace uses of the SILPhiArgument type and code that explicitly
handle block arguments. Control flow is irrelevant in these
situations. SILPhiArgument needs to be deleted ASAP. Instead, use
simple APIs like SILArgument::isTerminatorResult(). Eventually this
will be replaced by a TerminatorResult type.
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
The reason why we are doing this is that we want move only addresses to be
checked by the move only address checker and not the move operator address
checker.
rdar://102056097
Introduce `MacroExpansionExpr` and `MacroExpansionDecl` and plumb it through. Parse them in roughly the same way we parse `ObjectLiteralExpr`.
The syntax is gated under `-enable-experimental-feature Macros`.
The problem here is that the AutoreleasingUnsafeMutablePointer's LValue
component would given the following Swift:
```
public class C {}
@inline(never)
func updateC(_ p: AutoreleasingUnsafeMutablePointer<C>) -> () {
p.pointee = C()
}
public func test() -> C {
var cVar = C()
updateC(&cVar)
return cVar
}
```
generate the following SIL as part of setting cVar after returning from updateC.
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
assign %22 to %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
Once we are in Canonical SIL, we get the following SIL:
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
store %22 to [assign] %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
which destroy hoisting then modifies by hoisting the destroy by the store assign
before the copy_value:
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
destroy_addr %7 : $*C
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
store %22 to [init] %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
Given the appropriate Swift code, one could have that %21 is actually already
stored in %7 and has a ref count of 1. In such a case, the destroy_addr would
cause %21 to be deallocated before we can retain the value.
In order to fix this edge case as a bug fix, in the setter for
AutoreleasingUnsafeMutablePointer, we introduce a mark_dependence from the
copied value onto the memory. This ensures that destroy hoisting does not hoist
the destroy_addr past the mark_dependence, yielding correctness. That is we
generate the following SIL:
```
%18 = function_ref @$s11autorelease7updateCyySAyAA1CCGF : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> () // user: %19
%19 = apply %18(%17) : $@convention(thin) (AutoreleasingUnsafeMutablePointer<C>) -> ()
%20 = load [trivial] %8 : $*@sil_unmanaged C // user: %21
%21 = unmanaged_to_ref %20 : $@sil_unmanaged C to $C // user: %22
%22 = copy_value %21 : $C // user: %23
%23 = mark_dependence %22 : $C on %7 : $*C
assign %23 to %7 : $*C // id: %23
end_access %7 : $*C // id: %24
```
For those unfamiliar, mark_dependence specifies that any destroy of the memory
in %7 can not move before any use of %23.
rdar://99402398
There was a special case here to type-check `T.init` as a single closure
`{ args.. in T.init(args..) }`, but really, we can do that for any static
member applied to a static metatype base, including operators.
Also fix SILGen's function conversion peephole so it looks through
`as (T...) -> U` coercions that don't involve bridging.
Sometimes we emit a closure literal with escaping/nonthrowing/nonasync type
into a context that wants a nonescaping/throwing/async function, and it
ends up wrapped in a conversion. We can look through any of these and emit
the closure literal directly with those effects.
Previously, we would turn a key path literal like `\.foo` in function type
context into a double-wrapped closure like this:
```
foo(\.x) // before type checking
foo({ $kp$ in { $0[$kp$] } }(\.x)) // after type checking
```
in order to preserve the evaluation semantics of the key path literal. This
works but leads to some awkward raw SIL generated out of SILGen which misses
out on various SILGen peepholes and requires a fair number of passes to clean
up. The semantics can still be preserved with a single layer of closure, by
using a capture list:
```
foo({[$kp$ = \.x] in $0[$kp$] }) // after type checking
```
which generates better natural code out of SILGen, and is also (IMO) easier
to understand on human inspection.
Changing the AST representation did lead to a change in code generation that
interfered with the efficacy of CapturePropagation of key path literals; for
key path literals used as nonescaping closures, a mark_dependence of the
nonescaping function value on the key path was left behind, leaving the key
path object alive. The dependence is severed by the specialization done in
the pass, so update the pass to eliminate the dependence.
Compared to the previous patch, this version removes the attempt to have
the type-checked function expression carry the noescape-ness of its context,
and allows for coerceToType to introduce a function conversion instead, since
that FunctionConversionExpr is apparently load-bearing for default argument
generators.
We needed a way to describe an ABI-safe cast of an address
representing an LValue to implement `@preconcurrency` and
its injection of casts during accesses of members.
This new AST node, `ABISafeConversionExpr` models what is
essentially an `unchecked_addr_cast` in SIL when accessing
the LVAlue.
As of now I simply implemented it and the verification of
the node for the concurrency needs to ensure that it's not
misused by accident. If it finds use outside of that,
feel free to update the verifier.
These will never appear in the source language, but can arise
after substitution when the original type is a tuple type with
a pack expansion type.
Two examples:
- original type: (Int, T...), substitution T := {}
- original type: (T...), substitution T := {Int}
We need to model these correctly to maintain invariants.
Callers that previously used to rely on TupleType::get()
returning a ParenType now explicitly check for the one-element
case instead.
Start visiting LazyInitializerExpr for profiling,
such that we emit a profile counter when
initializing the initial value for the first time.
rdar://43393937
This change ensures all store_borrows are ended with an end_borrow, and uses of the store_borrow
destination are all in the enclosing store_borrow scope and via the store_borrow return address.
Fix tests to reflect new store_borrow pattern
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.
Rename the second one to a 'reduced type'.
I also updated the move function tests to show that this is working. As a nice
bonus, I was able to enable all of the tests also in a non-optimized stdlib.
* [NFC] Add a getOptionalityDepth method to return the number of optionals a type has
* [NFC] Use getOptionalityDepth to remove existing code
* [AST] Add a new diagnostic note for suggesting optional chaining
* [CSDiagnostics] Tweak MissingOptionalUnwrapFailure to suggest using optional chaining on closure
* [Test] Add a couple of test cases for perform_optional_chain_on_closure
* [CSDiagnostics] Change DeclRefExpr casts to isa checks
* [AST] Update diagnostic phrasing
* [Sema] Use new diagnostic identifier and update comment
* [Test] Add a new test case for function type
* [Test] Update cfuncs_parse.swift tests to check for new diagnostic note
Andy some time ago already created the new API but didn't go through and update
the old occurences. I did that in this PR and then deprecated the old API. The
tree is clean, so I could just remove it, but I decided to be nicer to
downstream people by deprecating it first.
This strategy is used to dispatch accesses to 'distributed' computed
property to distributed thunk accessor instead of a regular getter
when access happen outside actor isolation context.
Relying on the optionality depth of the 'new self' value to flatten
an extra level of optionality or handle a failure is not sufficient,
because we may be delegating to an `Optional` initializer.
Instead, flattening should occur if the result type of the enclosing
initializer is less optional than 'new self', and failure handling —
if the enclosing initializer is failable and its result type is as
optional as the potentially flattened 'new self' value.
TypeConverter doesn't know by itself what SILModule it's currently lowering on
behalf of, so the existing code forming the TypeExpansionContext for opaque types
incorrectly set the isWholeModule flag to always false. This created a miscompile
when a public API contained a closure that captured a value involving private types
from another file in the same module because of mismatched type expansion contexts
inside and outside the closure. Fixes rdar://93821679
Their definition is fully visible to clients to be copied into them, and there isn't necessarily
a symbol for the property descriptor in the defining module, so it isn't necessary or desirable to
try to use a property descriptor with them. Trying to reference the descriptor leads to missing
symbol errors at load time when trying to use keypaths with older versions of the defining dylib,
which goes against the purpose of `@_alwaysEmitIntoClient` meaning "no ABI liabilities for the
defining module". Fixes rdar://94049160.
Closure literals are sometimes type-checked as one type then immediately converted to another
type in the AST. One particular case of this is when a closure body never throws, but the closure
is used as an argument to a function that takes a parameter that `throws`. Emitting this naively,
by emitting the closure as its original type, then converting to throws, can be expensive for
async closures, since that takes a reabstraction thunk. Even for non-async functions, we still want
to get the benefit of reabstraction optimization for the closure literal through the conversion too.
So if the function conversion just add `throws`, emit the closure as throwing, and pass down the
context abstraction pattern when emitting the closure as well.
Stop pretending that an optional requirement is immutable via the `StorageImplInfo` request.
This approach has lead astray the conformance checker and may have had a negative impact
on other code paths, and it doesn't work for imported declarations because they bypass the
request. Instead, use a forwarding `AbstractStorageDecl::isSettableInSwift` method
that special-cases optional requirements.