SIL: Add fields to SILFunctionType for substituted function types. #27887
+1,173
−645
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711
This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:
A substitution map, accessed by
getSubstitutions()
, which maps the generic signatureof the function to its concrete implementation. This will allow, for instance, a protocol
witness for a requirement of type
<Self: P> (Self, ...) -> ...
for a concrete conformingtype
Foo
to express its type as<Self: P> (Self, ...) -> ... for <Foo>
, preserving the relationto the protocol interface without relying on the pile of hacks that is the
witness_method
protocol.
A bool for whether the generic signature of the function is "implied" by the substitutions.
If true, the generic signature isn't really part of the calling convention of the function.
This will allow closure types to distinguish a closure being passed to a generic function, like
<T, U> in (*T, *U) -> T for <Int, String>
, from the concrete type(*Int, *String) -> Int
,which will make it easier for us to differentiate the representation of those as types, for
instance by giving them different pointer authentication discriminators to harden arm64e
code.
This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.
This does bifurcate some existing APIs:
getSubstGenericSignature
gets the generic signature that is used to apply itssubstitution map, if any.
getInvocationGenericSignature
gets the generic signatureused to invoke the function at apply sites. These differ if the generic signature is
implied.
and results of the function. They now have two APIs to get that type.
getInterfaceType
returns the unsubstituted type of the generic interface, and
getArgumentType
/getReturnValueType
produce the substituted type that is used atapply sites.