Fixes a false alarm in case of recursive calls with different type parameters.
For example:
```
protocol P {
associatedtype E: P
}
func noRecursionMismatchingTypeArgs1<T: P>(_ t: T.Type) {
if T.self == Int.self {
return
}
noRecursionMismatchingTypeArgs1(T.E.self)
}
```
Run the swift-frontend in a mode that will generate LLVM IR adding the
option `-print-cond-fail-messages` will dump all cond_fail message strings
encountered in the SIL.
```
% swift-frontend -Xllvm -print-cond-fail-messages -emit-ir/-c ...
cond_fail message encountered: Can't take a prefix of negative length from a collection
cond_fail message encountered: Range out of bounds
cond_fail message encountered: Array index is out of range
```
OSLogOptimization pass
The OSLogOptimization pass constant evaluates and folds SIL instructions
that are inlined from the construction of the string interpolations passed
to the log calls, which enables replacing the dynamic format string construction
with a static format string. In addition to folding constant strings, it also folds
constant integers and arrays whose elements are constants. This change makes it
skip folding static strings, since they are already efficiently represented.
rdar://146028438
Only return false if the visitor returns false. Clients were ignoring the
result.
If the BorrowingOperand does not create a borrow scope, call visitUnknownUse
instead.
Until we have complete lifetimes, to avoid breaking code that cannot handle dead
defs, consider a dead borrow scope to be an unknown use.
If the default argument generator (and, consequently, the function taking this default argument) has public visibility, it's OK to have a closure (which always has private visibility) as the default value of the argument.
Inside fragile functions, we expect function derivatives to be public, which could be achieved by either explicitly marking the functions as differentiable or having a public explicit derivative defined for them. This is obviously not
possible for single and double curry thunks which are a special case of `AutoClosureExpr`.
Instead of looking at the thunk itself, we unwrap it and look at the function being wrapped. While the thunk itself and its differentiability witness will not have public visibility, it's not an issue for the case where the function being wrapped (and its witness) have public visibility.
Fixes#54819Fixes#75776
i```
swift\lib\SILOptimizer\Mandatory\MoveOnlyAddressCheckerUtils.cpp(2981): warning C5030: attribute [[clang::fallthrough]] is not recognized
```
Replace the use of `clang::fallthrough` with `LLVM_FALLTHROUGH` which
properly uses the C++ standard spelling (`[[fallthrough]]`) depending on
the compiler version.
This is necessary to fix a recent OSSA bug that breaks common occurrences on
mark_dependence [nonescaping]. Rather than reverting that change above, we make
forward progress toward implicit borrows scopes, as was the original intention.
In the near future, all InteriorPointer instructions will create an implicit
borrow scope. This means we have the option of not emitting extraneous
begin/end_borrow instructions around intructions like ref_element_addr,
open_existential, and project_box. After that, we can also migrate
GuaranteedForwarding instructions like tuple_extract and struct_extract.
The code here determined the borrow scope of an InteriorPointerOperand use of a borrow using
`visitBaseValueScopeEndingUses`, but it does so after rewriting the operand, so the base
value would sometimes be incorrect leading to missing `end_borrows` in the rewritten code.
Fixes rdar://133333278.
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.
Otherwise, when one diagnoses code like the following:
```
Task {
{
use($0)
}(x)
}
```
One gets that $0 was captured instead of x. Unfortunately, since function
parameters do not have locations associated with them, we do not mark x
itself... instead, we mark the closure... which is unfortunate.
The problem with `is_escaping_closure` was that it didn't consume its operand and therefore reference count checks were unreliable.
For example, copy-propagation could break it.
As this instruction was always used together with an immediately following `destroy_value` of the closure, it makes sense to combine both into a `destroy_not_escaped_closure`.
It
1. checks the reference count and returns true if it is 1
2. consumes and destroys the operand
Improves OSSALifetimeCompletion to handle trivial variables when running from
SILGenCleanup. This only affects lifetime dependence diagnostics.
For the purpose of lifetime diagnostics, trivial local variables are only valid
within their lexical scope. Sadly, SILGen only know how to insert cleanup code
on normal function exits. SILGenCleanup relies on lifetime completion to fix
lifetimes on dead end paths.
%var = move_value [var_decl]
try_apply %f() : $..., normal bb1, error error
error:
extend_lifetime %var <=== insert this
unreachable
This allows Span to depend on local unsafe pointers AND be used within
throwing closures:
_ = a.withUnsafeBufferPointer {
let buffer = $0
let view = Span(_unsafeElements: buffer)
return view.withUnsafeBufferPointer(\.count)
}
The reason why I am doing this is that in certain cases the AST captures indices
will never actually line up with partial apply capture indices since we seem to
"smush" together closures and locally defined functions.
NOTE: The reason for the really small amount of test changes is that this change
does not change the actual output by design. The only cases I had to change were
a case where we began to emit a better diagnostic and also where I added code
coverage around _ and let _ since those require ignored_use to be implemented so
that they would be diagnosed (previously we just did not emit anything so we
couldn't emit the diagnostic at the SIL level).
rdar://142661388
Preserve ownership for empty non-trivial structs. This currently applies to
~Escapable structs. People often use empty structs to investigate language
behavior. They should behave just like a struct that wraps a
pointer.
Previously, this would crash later during OSSA lifetime completion:
Assertion failed: (isa<UnreachableInst>(block->getTerminator())),
function computeRegion, file OSSALifetimeCompletion.cpp.
Only generate code lazily for such functions, i.e. only if such a function is referenced from already generated code.
This is achieved by converting the SILLinkage for `public_external` functions to `internal` instead of `public in IRGenPrepare.