|
10 | 10 | //
|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 | //
|
13 |
| -// This file implements logic for desugaring requirements, for example breaking |
14 |
| -// down 'T : P & Q' into 'T : P' and 'T : Q', as well as requirement inference, |
15 |
| -// where an occurrence of 'Set<T>' in a function signature introduces the |
16 |
| -// requirement 'T : Hashable' from the generic signature of 'struct Set'. |
| 13 | +// The process of constructing a requirement machine from some input requirements |
| 14 | +// can be summarized by the following diagram. |
| 15 | +// |
| 16 | +// ------------------ |
| 17 | +// / RequirementRepr / <-------- Generic parameter lists, 'where' clauses, |
| 18 | +// ------------------ and protocol definitions written in source |
| 19 | +// | start here: |
| 20 | +// | - InferredGenericSignatureRequest |
| 21 | +// | - RequirementSignatureRequest |
| 22 | +// v |
| 23 | +// +-------------------------+ ------------------- |
| 24 | +// | Requirement realization | --------> / Sema diagnostics / |
| 25 | +// +-------------------------+ ------------------- |
| 26 | +// | |
| 27 | +// | ------------------------------------- |
| 28 | +// | / Function parameter/result TypeRepr / |
| 29 | +// | ------------------------------------- |
| 30 | +// | | |
| 31 | +// | v |
| 32 | +// | +-----------------------+ |
| 33 | +// | | Requirement inference | |
| 34 | +// | +-----------------------+ |
| 35 | +// | | |
| 36 | +// | +---------------+ |
| 37 | +// v v |
| 38 | +// ------------------------ |
| 39 | +// / StructuralRequirement / <---- Minimization of a set of abstract |
| 40 | +// ------------------------ requirements internally by the compiler |
| 41 | +// | starts here: |
| 42 | +// | - AbstractGenericSignatureRequest |
| 43 | +// v |
| 44 | +// +------------------------+ ------------------- |
| 45 | +// | Requirement desugaring | -------> / RequirementError / |
| 46 | +// +------------------------+ ------------------- |
| 47 | +// | |
| 48 | +// v |
| 49 | +// -------------- |
| 50 | +// / Requirement / |
| 51 | +// -------------- |
| 52 | +// | |
| 53 | +// v |
| 54 | +// +----------------------+ |
| 55 | +// | Concrete contraction | |
| 56 | +// +----------------------+ |
| 57 | +// | ------------------------- |
| 58 | +// v / Existing RewriteSystem / |
| 59 | +// -------------- ------------------------- |
| 60 | +// / Requirement / | |
| 61 | +// -------------- v |
| 62 | +// | +--------------------------------------------+ |
| 63 | +// | | Importing rules from protocol dependencies | |
| 64 | +// | +--------------------------------------------+ |
| 65 | +// | | |
| 66 | +// | +------------------------------+ |
| 67 | +// | | |
| 68 | +// v v |
| 69 | +// +-------------+ |
| 70 | +// | RuleBuilder | <--- Construction of a rewrite system to answer |
| 71 | +// +-------------+ queries about an already-minimized generic |
| 72 | +// | signature or connected component of protocol |
| 73 | +// v requirement signatures starts here: |
| 74 | +// ------- - RewriteContext::getRequirementMachine() |
| 75 | +// / Rule / |
| 76 | +// ------- |
| 77 | +// |
| 78 | +// This file implements the "requirement realization", "requirement inference" |
| 79 | +// and "requirement desugaring" steps above. Concrete contraction is implemented |
| 80 | +// in ConcreteContraction.cpp. Building rewrite rules from desugared requirements |
| 81 | +// is implemented in RuleBuilder.cpp. |
| 82 | +// |
| 83 | +// # Requirement realization and inference |
| 84 | +// |
| 85 | +// Requirement realization takes parsed representations of generic requirements, |
| 86 | +// and converts them to StructuralRequirements: |
| 87 | +// |
| 88 | +// - RequirementReprs in 'where' clauses |
| 89 | +// - TypeReprs in generic parameter and associated type inheritance clauses |
| 90 | +// - TypeReprs of function parameters and results, for requirement inference |
| 91 | +// |
| 92 | +// Requirement inference is the language feature where requirements on type |
| 93 | +// parameters are inferred from bound generic type applications. For example, |
| 94 | +// in the following, 'T : Hashable' is not explicitly stated: |
| 95 | +// |
| 96 | +// func foo<T>(_: Set<T>) {} |
| 97 | +// |
| 98 | +// The application of the bound generic type "Set<T>" requires that |
| 99 | +// 'T : Hashable', from the generic signature of the declaration of 'Set'. |
| 100 | +// Requirement inference, when performed, will introduce this requirement. |
| 101 | +// |
| 102 | +// Requirement realization calls into Sema' resolveType() and similar operations |
| 103 | +// and emits diagnostics that way. |
| 104 | +// |
| 105 | +// # Requirement desugaring |
| 106 | +// |
| 107 | +// Requirements in 'where' clauses allow for some unneeded generality that we |
| 108 | +// eliminate early. For example: |
| 109 | +// |
| 110 | +// - The right hand side of a protocol conformance requirement might be a |
| 111 | +// protocol composition. |
| 112 | +// |
| 113 | +// - Same-type requirements involving concrete types can take various forms: |
| 114 | +// a) Between a type parameter and a concrete type, eg. 'T == Int'. |
| 115 | +// b) Between a concrete type and a type parameter, eg. 'Int == T'. |
| 116 | +// c) Between two concrete types, eg 'Array<T> == Array<Int>'. |
| 117 | +// |
| 118 | +// 'Desugared requirements' take the following special form: |
| 119 | +// |
| 120 | +// - The subject type of a requirement is always a type parameter. |
| 121 | +// |
| 122 | +// - The right hand side of a conformance requirement is always a single |
| 123 | +// protocol. |
| 124 | +// |
| 125 | +// - A concrete same-type requirement is always between a type parameter and |
| 126 | +// a concrete type. |
| 127 | +// |
| 128 | +// The desugaring process eliminates requirements where both sides are |
| 129 | +// concrete by evaluating them immediately, reporting an error if the |
| 130 | +// requirement does not hold, or a warning if it is trivially true. |
| 131 | +// |
| 132 | +// Conformance requirements with protocol compositions on the right hand side |
| 133 | +// are broken down into multiple conformance requirements. |
| 134 | +// |
| 135 | +// Same-type requirements where both sides are concrete are decomposed by |
| 136 | +// walking the two concrete types in parallel. If there is a mismatch in the |
| 137 | +// concrete structure, an error is recorded. If a mismatch involves a concrete |
| 138 | +// type and a type parameter, a new same-type requirement is recorded. |
| 139 | +// |
| 140 | +// For example, in the above, 'Array<T> == Array<Int>' is desugared into the |
| 141 | +// single requirement 'T == Int'. |
| 142 | +// |
| 143 | +// Finally, same-type requirements between a type parameter and concrete type |
| 144 | +// are oriented so that the type parameter always appears on the left hand side. |
| 145 | +// |
| 146 | +// Requirement desugaring diagnoses errors by building a list of |
| 147 | +// RequirementError values. |
17 | 148 | //
|
18 | 149 | //===----------------------------------------------------------------------===//
|
19 | 150 |
|
|
33 | 164 | using namespace swift;
|
34 | 165 | using namespace rewriting;
|
35 | 166 |
|
| 167 | +// |
| 168 | +// Requirement desugaring |
| 169 | +// |
| 170 | + |
36 | 171 | /// Desugar a same-type requirement that possibly has concrete types on either
|
37 | 172 | /// side into a series of same-type and concrete-type requirements where the
|
38 | 173 | /// left hand side is always a type parameter.
|
@@ -248,11 +383,7 @@ swift::rewriting::desugarRequirement(Requirement req,
|
248 | 383 | }
|
249 | 384 |
|
250 | 385 | //
|
251 |
| -// StructuralRequirementsRequest computation. |
252 |
| -// |
253 |
| -// This realizes RequirementReprs into Requirements, desugars them using the |
254 |
| -// above, performs requirement inference, and wraps them with source location |
255 |
| -// information. |
| 386 | +// Requirement realization and inference. |
256 | 387 | //
|
257 | 388 |
|
258 | 389 | static void realizeTypeRequirement(Type subjectType, Type constraintType,
|
@@ -638,6 +769,11 @@ bool swift::rewriting::diagnoseRequirementErrors(
|
638 | 769 | return diagnosedError;
|
639 | 770 | }
|
640 | 771 |
|
| 772 | +/// StructuralRequirementsRequest realizes all the user-written requirements |
| 773 | +/// on the associated type declarations inside of a protocol. |
| 774 | +/// |
| 775 | +/// This request is invoked by RequirementSignatureRequest for each protocol |
| 776 | +/// in the connected component. |
641 | 777 | ArrayRef<StructuralRequirement>
|
642 | 778 | StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
|
643 | 779 | ProtocolDecl *proto) const {
|
@@ -740,6 +876,14 @@ StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
|
740 | 876 | return ctx.AllocateCopy(result);
|
741 | 877 | }
|
742 | 878 |
|
| 879 | +/// This request primarily emits diagnostics about typealiases and associated |
| 880 | +/// type declarations that override another associate type, and can better be |
| 881 | +/// expressed as requirements in the 'where' clause. |
| 882 | +/// |
| 883 | +/// It also implements a compatibility behavior where sometimes typealiases in |
| 884 | +/// protocol extensions would introduce requirements in the |
| 885 | +/// GenericSignatureBuilder, if they had the same name as an inherited |
| 886 | +/// associated type. |
743 | 887 | ArrayRef<Requirement>
|
744 | 888 | TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
|
745 | 889 | ProtocolDecl *proto) const {
|
|
0 commit comments