## Summary
This PR fixes the ODR violation detailed in
https://github.com/swiftlang/swift/issues/87917
## Impl
When specializeClosure determines the specialized closure remains
generic (`isGeneric == true`), clone the body without applying type
substitutions, and use `partial_apply` with the substitution map at the
call site instead of `thin_to_thick_function`. The body stays generic
with type parameters like `$*Optional<Self>`, which is correct since all
callers share the same shared symbol and apply their own concrete types
through the substitution map on the `partial_apply`.
## Tests
Add SIL and executable tests demonstrating that
ConstantCapturePropagation produces an ODR violation when specializing
generic closures with different concrete type substitutions but the same
constant captures.
The SIL test provides a minimal reproducer: two callers instantiate the
same generic closure with UInt8 and Int respectively, both capturing
constant `radix=10`. With `-enable-sil-verify-all`, the verifier catches
the type mismatch in the specialized function body.
The executable test exercises the real-world scenario through
`FixedWidthInteger.init?(_:radix:)`, where the miscompile causes Int and
`Int32` parsing to return garbage values because the closure body was
baked with `UInt8` type metadata.
Fixes: https://github.com/swiftlang/swift/issues/87917
[Assisted-by](https://t.ly/Dkjjk): [Claude Opus
4.6](https://www.anthropic.com/news/claude-opus-4-6)
cc @drodriguez @kyulee-com
* convert "method"s to "thin" functions: We are removing arguments from the original function. If the removed argument is the "self" argument, the specialized function cannot be a "method" anymore.
* don't create `thin_to_thick_function` instructions for non-thin functions. Instead keep it a `partial_apply`
Fixes a SIL verifier crash.
rdar://172774069
* All SIL modifications must go through a `MutatingContext`. Therefore replace the simple setter for `isNested` with `set(isNested:, context)`
* It's better to add a `isNested` parameter for `Builder.createPartialApply` than to set it after each construction of a `partial_apply`, which can easily be missed.
This is needed if the guaranteed argument is replaced by a copied owned value. If the argument has any use which is not compatible with "owned" ownership, we need a borrow scope.
This new OSSA invariant simplifies many optimizations because they don't have to take care of the corner case of incomplete lifetimes in dead-end blocks.
The implementation basically consists of these changes:
* add the lifetime completion utility
* add a flag in SILFunction which tells optimization that they need to run the lifetime completion utility
* let all optimizations complete lifetimes if necessary
* enable the ownership verifier to check complete lifetimes
* remove `filterUsers(ofType:)`, because it's a duplication of `users(ofType:)`
* rename `filterUses(ofType:)` -> `filter(usersOfType:)`
* rename `ignoreUses(ofType:)` -> `ignore(usersOfType:)`
* rename `getSingleUser` -> `singleUser`
* implement `singleUse` with `Sequence.singleElement`
* implement `ignoreDebugUses` with `ignore(usersOfType:)`
This is a follow-up of https://github.com/swiftlang/swift/pull/83728/commits/eb1d5f484c9f4dae73a3779191bfdf917fd07a49.
We cannot do this because we don't know where to insert the compensating release after the propagated `partial_apply`.
A required `strong_retain` may have been moved over the `partial_apply`.
Then we would release the keypath too early.
Fixes a mis-compile
rdar://161321614
(old name: CapturePropagation)
The pass is now rewritten in swift which makes the code smaller and simpler.
Compared to the old pass it has two improvements:
* It can constant propagate whole structs (and not only builtin literals). This is important for propagating "real" Swift constants which have a struct type of e.g. `Int`.
* It constant propagates keypaths even if there are other non-constant closure captures which are not propagated. This is something the old pass didn't do.
rdar://151185177