Skip to content

Commit 1f62fe5

Browse files
authored
Merge pull request swiftlang#30272 from rjmccall/invocation-sil-function-subs
Distinguish invocation and pattern substitutions on SILFunctionType
2 parents 44e155f + ceff414 commit 1f62fe5

File tree

96 files changed

+1256
-624
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1256
-624
lines changed

docs/ABI/Mangling.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -583,10 +583,12 @@ mangled in to disambiguate.
583583
::
584584

585585
impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_'
586-
impl-function-type ::= type* generic-signature 'I' PSEUDO-GENERIC? FUNC-ATTRIBUTES '_'
586+
impl-function-type ::= type* generic-signature 'I' FUNC-ATTRIBUTES '_'
587587

588-
FUNC-ATTRIBUTES ::= CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? PARAM-CONVENTION* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)?
588+
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? PARAM-CONVENTION* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)?
589589

590+
PATTERN-SUBS ::= 's' // has pattern substitutions
591+
INVOCATION-SUB ::= 'I' // has invocation substitutions
590592
PSEUDO-GENERIC ::= 'P'
591593

592594
CALLEE-ESCAPE ::= 'e' // @escaping (inverse of SIL @noescape)

docs/SIL.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,46 @@ autorelease in the callee.
592592
importer only imports non-native methods and types as ``throws``
593593
when it is possible to do this automatically.
594594

595+
- SIL function types may provide a pattern signature and substitutions
596+
to express that values of the type use a particular generic abstraction
597+
pattern. Both must be provided together. If a pattern signature is
598+
present, the component types (parameters, yields, and results) must be
599+
expressed in terms of the generic parameters of that signature.
600+
The pattern substitutions should be expressed in terms of the generic
601+
parameters of the overall generic signature, if any, or else
602+
the enclosing generic context, if any.
603+
604+
A pattern signature follows the ``@substituted`` attribute, which
605+
must be the final attribute preceding the function type. Pattern
606+
substitutions follow the function type, preceded by the ``for``
607+
keyword. For example::
608+
609+
@substituted <T: Collection> (@in T) -> @out T.Element for Array<Int>
610+
611+
The low-level representation of a value of this type may not match
612+
the representation of a value of the substituted-through version of it::
613+
614+
(@in Array<Int>) -> @out Int
615+
616+
Substitution differences at the outermost level of a function value
617+
may be adjusted using the ``convert_function`` instruction. Note that
618+
this only works at the outermost level and not in nested positions.
619+
For example, a function which takes a parameter of the first type above
620+
cannot be converted by ``convert_function`` to a function which takes
621+
a parameter of the second type; such a conversion must be done with a
622+
thunk.
623+
624+
Type substitution on a function type with a pattern signature and
625+
substitutions only substitutes into the substitutions; the component
626+
types are preserved with their exact original structure.
627+
628+
- In the implementation, a SIL function type may also carry substitutions
629+
for its generic signature. This is a convenience for working with
630+
applied generic types and is not generally a formal part of the SIL
631+
language; in particular, values should not have such types. Such a
632+
type behaves like a non-generic type, as if the substitutions were
633+
actually applied to the underlying function type.
634+
595635
Coroutine Types
596636
```````````````
597637

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,14 @@ ERROR(sil_function_subst_expected_l_angle,none,
828828
"expected '<' to begin SIL function type substitution list after 'for'", ())
829829
ERROR(sil_function_subst_expected_r_angle,none,
830830
"expected '>' to end SIL function type substitution list after 'for <...'", ())
831+
ERROR(sil_function_subst_expected_generics,none,
832+
"expected '<' to begin substituted parameter list after '@substituted'", ())
833+
ERROR(sil_function_subst_expected_function,none,
834+
"expected function type after '@substituted'", ())
835+
ERROR(sil_function_subst_expected_subs,none,
836+
"expected 'for' to begin substitutions after '@substituted' function type", ())
837+
ERROR(sil_function_subs_without_generics,none,
838+
"unexpected 'for' to begin substitutions after non-generic function type", ())
831839

832840
// Opaque types
833841
ERROR(opaque_mid_composition,none,

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4019,6 +4019,8 @@ ERROR(sil_non_coro_yields,PointsToFirstBadToken,
40194019
ERROR(sil_function_repeat_convention,PointsToFirstBadToken,
40204020
"repeated %select{parameter|result|callee}0 convention attribute",
40214021
(unsigned))
4022+
ERROR(ast_subst_function_type,none,
4023+
"substitutions cannot be provided on a formal function type", ())
40224024
ERROR(sil_function_multiple_error_results,PointsToFirstBadToken,
40234025
"SIL function types cannot have multiple @error results", ())
40244026
ERROR(unsupported_sil_convention,none,

include/swift/AST/TypeRepr.h

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -472,12 +472,15 @@ inline IdentTypeRepr::ComponentRange IdentTypeRepr::getComponentRange() {
472472
/// (x: Foo, y: Bar) -> Baz
473473
/// \endcode
474474
class FunctionTypeRepr : public TypeRepr {
475-
// These fields are only used in SIL mode, which is the only time
476-
// we can have polymorphic and substituted function values.
475+
// The generic params / environment / substitutions fields are only used
476+
// in SIL mode, which is the only time we can have polymorphic and
477+
// substituted function values.
477478
GenericParamList *GenericParams;
478479
GenericEnvironment *GenericEnv;
479-
bool GenericParamsAreImplied;
480-
ArrayRef<TypeRepr *> GenericSubs;
480+
ArrayRef<TypeRepr *> InvocationSubs;
481+
GenericParamList *PatternGenericParams;
482+
GenericEnvironment *PatternGenericEnv;
483+
ArrayRef<TypeRepr *> PatternSubs;
481484

482485
TupleTypeRepr *ArgsTy;
483486
TypeRepr *RetTy;
@@ -487,21 +490,37 @@ class FunctionTypeRepr : public TypeRepr {
487490
public:
488491
FunctionTypeRepr(GenericParamList *genericParams, TupleTypeRepr *argsTy,
489492
SourceLoc throwsLoc, SourceLoc arrowLoc, TypeRepr *retTy,
490-
bool GenericParamsAreImplied = false,
491-
ArrayRef<TypeRepr *> GenericSubs = {})
493+
GenericParamList *patternGenericParams = nullptr,
494+
ArrayRef<TypeRepr *> patternSubs = {},
495+
ArrayRef<TypeRepr *> invocationSubs = {})
492496
: TypeRepr(TypeReprKind::Function),
493-
GenericParams(genericParams),
494-
GenericEnv(nullptr),
495-
GenericParamsAreImplied(GenericParamsAreImplied),
496-
GenericSubs(GenericSubs),
497+
GenericParams(genericParams), GenericEnv(nullptr),
498+
InvocationSubs(invocationSubs),
499+
PatternGenericParams(patternGenericParams), PatternGenericEnv(nullptr),
500+
PatternSubs(patternSubs),
497501
ArgsTy(argsTy), RetTy(retTy),
498502
ArrowLoc(arrowLoc), ThrowsLoc(throwsLoc) {
499503
}
500504

501505
GenericParamList *getGenericParams() const { return GenericParams; }
502506
GenericEnvironment *getGenericEnvironment() const { return GenericEnv; }
503-
bool areGenericParamsImplied() const { return GenericParamsAreImplied; }
504-
ArrayRef<TypeRepr*> getSubstitutions() const { return GenericSubs; }
507+
508+
GenericParamList *getPatternGenericParams() const {
509+
return PatternGenericParams;
510+
}
511+
GenericEnvironment *getPatternGenericEnvironment() const {
512+
return PatternGenericEnv;
513+
}
514+
515+
ArrayRef<TypeRepr*> getPatternSubstitutions() const { return PatternSubs; }
516+
ArrayRef<TypeRepr*> getInvocationSubstitutions() const {
517+
return InvocationSubs;
518+
}
519+
520+
void setPatternGenericEnvironment(GenericEnvironment *genericEnv) {
521+
assert(PatternGenericEnv == nullptr);
522+
PatternGenericEnv = genericEnv;
523+
}
505524

506525
void setGenericEnvironment(GenericEnvironment *genericEnv) {
507526
assert(GenericEnv == nullptr);

0 commit comments

Comments
 (0)