|
41 | 41 | #include "swift/Serialization/SerializedModuleLoader.h"
|
42 | 42 | #include "llvm/ADT/ScopedHashTable.h"
|
43 | 43 | #include "llvm/ADT/SmallString.h"
|
| 44 | +#include "llvm/ADT/Statistic.h" |
44 | 45 | #include "llvm/Support/Compiler.h"
|
45 | 46 | #include "llvm/Support/ErrorHandling.h"
|
46 | 47 | #include "llvm/Support/SaveAndRestore.h"
|
47 | 48 |
|
48 |
| -#define DEBUG_TYPE "protocol-conformance-checking" |
| 49 | +#define DEBUG_TYPE "Protocol conformance checking" |
49 | 50 | #include "llvm/Support/Debug.h"
|
50 | 51 |
|
| 52 | +STATISTIC(NumRequirementEnvironments, "# of requirement environments"); |
| 53 | + |
51 | 54 | using namespace swift;
|
52 | 55 |
|
53 | 56 | namespace {
|
@@ -1065,26 +1068,19 @@ RequirementEnvironment::RequirementEnvironment(
|
1065 | 1068 | auto selfType = cast<GenericTypeParamType>(
|
1066 | 1069 | proto->getSelfInterfaceType()->getCanonicalType());
|
1067 | 1070 |
|
1068 |
| - // Construct a generic signature builder by collecting the constraints |
1069 |
| - // from the requirement and the context of the conformance together, |
1070 |
| - // because both define the capabilities of the requirement. |
1071 |
| - GenericSignatureBuilder builder( |
1072 |
| - ctx, |
1073 |
| - TypeChecker::LookUpConformance(tc, conformanceDC)); |
1074 |
| - |
1075 | 1071 | SmallVector<GenericTypeParamType*, 4> allGenericParams;
|
1076 | 1072 |
|
1077 | 1073 | // Add the generic signature of the context of the conformance. This includes
|
1078 | 1074 | // the generic parameters from the conforming type as well as any additional
|
1079 | 1075 | // constraints that might occur on the extension that declares the
|
1080 | 1076 | // conformance (i.e., if the conformance is conditional).
|
| 1077 | + GenericSignature *conformanceSig; |
1081 | 1078 | unsigned depth = 0;
|
1082 |
| - if (auto *conformanceSig = conformanceDC->getGenericSignatureOfContext()) { |
| 1079 | + if ((conformanceSig = conformanceDC->getGenericSignatureOfContext())) { |
1083 | 1080 | // Use the canonical signature here.
|
1084 | 1081 | conformanceSig = conformanceSig->getCanonicalSignature();
|
1085 | 1082 | allGenericParams.append(conformanceSig->getGenericParams().begin(),
|
1086 | 1083 | conformanceSig->getGenericParams().end());
|
1087 |
| - builder.addGenericSignature(conformanceSig); |
1088 | 1084 | depth = allGenericParams.back()->getDepth() + 1;
|
1089 | 1085 | }
|
1090 | 1086 |
|
@@ -1138,12 +1134,29 @@ RequirementEnvironment::RequirementEnvironment(
|
1138 | 1134 | GenericTypeParamType::get(depth, genericParam->getIndex(), ctx);
|
1139 | 1135 |
|
1140 | 1136 | allGenericParams.push_back(substGenericParam);
|
1141 |
| - builder.addGenericParameter(substGenericParam); |
1142 | 1137 | }
|
1143 | 1138 |
|
1144 | 1139 | // If there were no generic parameters, we're done.
|
1145 | 1140 | if (allGenericParams.empty()) return;
|
1146 | 1141 |
|
| 1142 | + // Construct a generic signature builder by collecting the constraints |
| 1143 | + // from the requirement and the context of the conformance together, |
| 1144 | + // because both define the capabilities of the requirement. |
| 1145 | + GenericSignatureBuilder builder( |
| 1146 | + ctx, |
| 1147 | + TypeChecker::LookUpConformance(tc, conformanceDC)); |
| 1148 | + |
| 1149 | + unsigned firstGenericParamToAdd = 0; |
| 1150 | + if (conformanceSig) { |
| 1151 | + builder.addGenericSignature(conformanceSig); |
| 1152 | + firstGenericParamToAdd = conformanceSig->getGenericParams().size(); |
| 1153 | + } |
| 1154 | + |
| 1155 | + for (unsigned gp : range(firstGenericParamToAdd, allGenericParams.size())) |
| 1156 | + builder.addGenericParameter(allGenericParams[gp]); |
| 1157 | + |
| 1158 | + ++NumRequirementEnvironments; |
| 1159 | + |
1147 | 1160 | // Next, add each of the requirements (mapped from the requirement's
|
1148 | 1161 | // interface types into the abstract type parameters).
|
1149 | 1162 | auto source =
|
|
0 commit comments