@@ -891,6 +891,123 @@ class TranslateIndirect : public Cleanup {
891
891
}
892
892
};
893
893
894
+ // / Given a list of inputs that are suited to the parameters of one
895
+ // / function, translate them into a list of outputs that are suited
896
+ // / for the parameters of another function, given that the two
897
+ // / functions differ only by abstraction differences and/or a small
898
+ // / a small set of subtyping-esque conversions tolerated by the
899
+ // / type checker.
900
+ // /
901
+ // / This is a conceptually rich transformation, and there are several
902
+ // / different concepts of expansion and transformation going on at
903
+ // / once here. We will briefly review these concepts in order to
904
+ // / explain what has to happen here.
905
+ // /
906
+ // / Swift functions have *formal* parameters. These are represented here
907
+ // / as the list of input and and output `CanParam` structures. The
908
+ // / type-checker requires function types to be formally related to each
909
+ // / in specific ways in order for a conversion to be accepted; this
910
+ // / includes the parameter lists being the same length (other than
911
+ // / the exception of SE-0110's tuple-splat behavior).
912
+ // /
913
+ // / SIL functions have *lowered* parameters. These correspond to the
914
+ // / SIL values we receive in Inputs and must generate in Outputs.
915
+ // /
916
+ // / A single formal parameter can correspond to any number of
917
+ // / lowered parameters because SIL function type lowering recursively
918
+ // / expands tuples that aren't being passed inout.
919
+ // /
920
+ // / The lowering of generic Swift function types must be independent
921
+ // / of the actual types substituted for generic parameters, which means
922
+ // / that decisions about when to expand must be made according to the
923
+ // / orig (unsubstituted) function type, not the substituted types.
924
+ // / But the type checker only cares that function types are related
925
+ // / as substituted types, so we may need to combine or expand tuples
926
+ // / because of the differences between abstraction.
927
+ // /
928
+ // / This translation therefore recursively walks the orig parameter
929
+ // / types of the input and output function type and expects the
930
+ // / corresponding lowered parameter lists to match with the structure
931
+ // / we see there. When the walk reaches a non-tuple orig type on the
932
+ // / input side, we know that the input function receives a lowered
933
+ // / parameter and therefore there is a corresponding value in Inputs.
934
+ // / When the walk reaches a non-tuple orig type on the output side,
935
+ // / we know that the output function receives a lowered parameter
936
+ // / and therefore there is a corresponding type in OutputTypes (and
937
+ // / a need to produce an argument value in Outputs).
938
+ // /
939
+ // / Variadic generics complicate this because both tuple element
940
+ // / lists and function formal parameter lists can contain pack
941
+ // / expansions. Again, the relevant question is where expansions
942
+ // / appear in the orig type; the substituted parameters / tuple
943
+ // / elements are still required to be related by the type-checker.
944
+ // / Like any other non-tuple pattern, an expansion always corresponds
945
+ // / to a single lowered parameter, which may then include multiple
946
+ // / formal parameters or tuple elements from the substituted type's
947
+ // / perspective. The orig type should carry precise substitutions
948
+ // / that will tell us how many components the expansion expands to,
949
+ // / which we must use to inform our recursive walk. These components
950
+ // / may or may not still contain pack expansions in the substituted
951
+ // / types; if they do, they will have the same shape.
952
+ // /
953
+ // / An example might help. Suppose that we have a generic function
954
+ // / that returns a function value:
955
+ // /
956
+ // / func produceFunction<T_0, each T_1>() ->
957
+ // / (Optional<T_0>, (B, C), repeat Array<each T_1>) -> ()
958
+ // /
959
+ // / And suppose we call this with generic arguments <A, Pack{D, E}>.
960
+ // / Then formally we now have a function of type:
961
+ // /
962
+ // / (Optional<A>, (B, C), Array<D>, Array<E>) -> ()
963
+ // /
964
+ // / These are the orig and subst formal parameter sequences. The
965
+ // / lowered parameter sequence of this type (assuming all the concrete
966
+ // / types A,B,... are non-trivial but loadable) is:
967
+ // /
968
+ // / (@in_guaranteed Optional<A>,
969
+ // / @guaranteed B,
970
+ // / @guaranteed C,
971
+ // / @pack_guaranteed Pack{Array<D>, Array<E>})
972
+ // /
973
+ // / Just for edification, if we had written this function type in a
974
+ // / non-generic context, it would have this lowered parameter sequence:
975
+ // /
976
+ // / (@guaranteed Optional<A>,
977
+ // / @guaranteed B,
978
+ // / @guaranteed C,
979
+ // / @guaranteed Array<D>,
980
+ // / @guaranteed Array<E>)
981
+ // /
982
+ // / Now suppose we also have a function that takes a function value:
983
+ // /
984
+ // / func consumeFunction<T_out_0, each T_out_1>(
985
+ // / _ function: (A, T_out_0, repeat each T_out_1, Array<E>) -> ()
986
+ // / )
987
+ // /
988
+ // / If we call this with the generic arguments <(B, C), Pack{Array<D>}>,
989
+ // / then it will expect a value of type:
990
+ // /
991
+ // / (A, (B, C), Array<D>, Array<E>) -> ()
992
+ // /
993
+ // / This is a supertype of the function type above (because of the
994
+ // / contravariance of function parameters), and so the type-checker will
995
+ // / permit the result of one call to be passed to the other. The
996
+ // / lowered parameter sequence of this type will be:
997
+ // /
998
+ // / (@guaranteed A,
999
+ // / @in_guaranteed (B, C),
1000
+ // / @in_guaranteed Array<D>,
1001
+ // / @guaranteeed Array<E>)
1002
+ // /
1003
+ // / We will then end up in this code with the second type as the input
1004
+ // / type and the first type as the output type. (The second type is
1005
+ // / the input because of contravariance again: we do this conversion
1006
+ // / by capturing a value of the first function type in a closure which
1007
+ // / presents the interface of the second function type. In this code,
1008
+ // / we are emitting the body of that closure, and therefore the inputs
1009
+ // / we receive are the parameters of that closure, matching the lowered
1010
+ // / signature of the second function type.)
894
1011
class TranslateArguments {
895
1012
SILGenFunction &SGF;
896
1013
SILLocation Loc;
0 commit comments