When performing a dynamic cast to an existential type that satisfies
(Metatype)Sendable, it is unsafe to allow isolated conformances of any
kind to satisfy protocol requirements for the existential. Identify
these cases and mark the corresponding cast instructions with a new flag,
`[prohibit_isolated_conformances]` that will be used to indicate to the
runtime that isolated conformances need to be rejected.
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)
}
```
The lifetime of yielded values always end at the end_apply.
This is required because a yielded address is non-aliasing inside the begin/end_apply scope, but might be aliasing after the end_apply.
For example, if the callee yields an `ref_element_addr` (which is encapsulated in a begin/end_access).
Therefore, even if the callee does not write anything, the effects must be "read" and "write".
Fixes a SIL verifier error
rdar://147601749
With this approach, you cannot tell whether a parameter is addressable only
from the function type. Instead you need the SILValue that will be passed to the
call site.
The Protocol field isn't really necessary, because the conformance
stores the protocol. But we do need the substituted subject type
of the requirement, just temporarily, until an abstract conformance
stores its own subject type too.
Casts always work with formal rather than lowered types.
This fixes a potential bug when lowered types are different than formal types, like function types.
* let `SIL.Type` conform to `TypeProperties` to share the implementation of common type properties between the AST types and `SIL.Type`
* call references to an `AST.Type` `rawType` (instead of just `type`)
* remove unneeded stuff
* add comments
InteriorLiveness has a new "visitInnerUses" mode used by DestroyHoisting. That
mode may visit dependent values, which was not valid for noescape
closures. ClosureLifetimeFixup inserts destroys of noescape closures after the
destroys of the captures. So following such dependent value could result in an
apparent use-after-destroy. This causes DestroyHoisting to insert redundant
destroys.
Fix: InteriorUses will conservatively only follow dependent values if they are
escapable. Non-escapable values, like noescape closures are now considered
escapes of the original value that the non-escapable value depends on. This can
be improved in the future, but we may want to rewrite ClosureLifetimeFixup first.
Fixes the root cause of: rdar://146142041
When creating a specialized witness table, we need to get the right specialized conformance.
In IRGen don't emit associated conformance witness table entries if the protocol is not a class protocol.
In this case the associated type can never be used to create an existential. Therefore such a witness table entry is never used at runtime in embedded swift.
Fixes a compiler crash
rdar://146448091
Otherwise, DestroyHoisting attemps to compute interior liveness
and inserts destoys at the ends. CanonicalizeOSSALifetimes is
designed to do this and not DestroyHoisting.
* Reimplement most of the logic in Swift as an Instruction simplification and remove the old code from SILCombine
* support more cases of existential archetype replacements:
For example:
```
%0 = alloc_stack $any P
%1 = init_existential_addr %0, $T
use %1
```
is transformed to
```
%0 = alloc_stack $T
use %0
```
Also, if the alloc_stack is already an opened existential and the concrete type is known,
replace it as well:
```
%0 = metatype $@thick T.Type
%1 = init_existential_metatype %0, $@thick any P.Type
%2 = open_existential_metatype %1 : $@thick any P.Type to $@thick (@opened("X", P) Self).Type
...
%3 = alloc_stack $@opened("X", any P) Self
use %3
```
is transformed to
```
...
%3 = alloc_stack $T
use %3
```
If an apply uses an existential archetype (`@opened("...")`) and the concrete type is known, replace the existential archetype with the concrete type
1. in the apply's substitution map
2. in the arguments, e.g. by inserting address casts
For example:
```
%5 = apply %1<@opend("...")>(%2) : <τ_0_0> (τ_0_0) -> ()
```
->
```
%4 = unchecked_addr_cast %2 to $*ConcreteType
%5 = apply %1<ConcreteType>(%4) : <τ_0_0> (τ_0_0) -> ()
```
* factor out common methods of AST Type/CanonicalType into a `TypeProperties` protocol.
* add more APIs to AST Type/CanoncialType.
* move `MetatypeRepresentation` from SIL.Type to AST.Type and implement it with a swift enum.
* let `Builder.createMetatype` get a CanonicalType as instance type, because the instance type must not be a lowered type.
Replace `unconditional_checked_cast` to an existential metatype with an `init_existential_metatype`, it the source is a conforming type.
Note that init_existential_metatype is better than unconditional_checked_cast because it does not need to do any runtime casting.
Check if an operand's instruction has been deleted in `UseList.next()`.
This allows to delete an instruction, which has two uses of a value, during use-list iteration.
allLifetimeEndingInstructions collects insertion points for end_borrows,
and can end up having duplicate entries in the case of enums with non payloaded cases.
Unique the entries so we don't end up with multiple end_borrows
Fixes rdar://146212574
DestroyHoisting is using this utility. This requires complete liveness. But we
can't rely on complete liveness because complete lifetimes is not
enabled. Instead, we use a visitInnerUses flag to try to ignore borrow
scopes. That flag was never properly implemented. Make an attempt here.
Always visit the use even if it is the beginning of an inner borrow. This
provides a "better" liveness result in the case of dead borrows and gives the
client a chance to see/intercept all uses.
Set the visitInnerUses flag. This is only a quick, partial fix.
InteriorUseWalker does not generate complete liveness for two reasons
1. pointer escapes. The client must always check for escapes before assuming
complete liveness.
2. dead end blocks. Until we have complete OSSA lifetimes, the algorithm for
handling nested borrows is incorrect. The visitInnerUses flag works around this
problem, but it isn't well tested and I'm not sure it's properly records escapes yet.