@@ -1087,85 +1087,104 @@ static void visitOuterToInner(
1087
1087
visitor (genericParams);
1088
1088
}
1089
1089
1090
+ // / Retrieve the generic parameter depth of the extended type.
1091
+ static unsigned getExtendedTypeGenericDepth (ExtensionDecl *ext) {
1092
+ auto nominal = ext->getAsNominalTypeOrNominalTypeExtensionContext ();
1093
+ if (!nominal) return static_cast <unsigned >(-1 );
1094
+
1095
+ auto sig = nominal->getGenericSignatureOfContext ();
1096
+ if (!sig) return static_cast <unsigned >(-1 );
1097
+
1098
+ return sig->getGenericParams ().back ()->getDepth ();
1099
+ }
1100
+
1090
1101
GenericEnvironment *TypeChecker::checkGenericEnvironment (
1091
1102
GenericParamList *genericParams,
1092
1103
DeclContext *dc,
1093
1104
GenericSignature *parentSig,
1094
1105
bool allowConcreteGenericParams,
1106
+ ExtensionDecl *ext,
1095
1107
llvm::function_ref<void (GenericSignatureBuilder &)>
1096
1108
inferRequirements) {
1097
1109
assert (genericParams && " Missing generic parameters?" );
1098
1110
bool recursivelyVisitGenericParams =
1099
1111
genericParams->getOuterParameters () && !parentSig;
1100
1112
1101
- // Collect the generic parameters.
1102
- SmallVector<GenericTypeParamType *, 4 > allGenericParams;
1103
- if (recursivelyVisitGenericParams) {
1104
- visitOuterToInner (genericParams,
1105
- [&](GenericParamList *gpList) {
1106
- addGenericParamTypes (gpList, allGenericParams);
1107
- });
1108
- } else {
1109
- if (parentSig) {
1110
- allGenericParams.append (parentSig->getGenericParams ().begin (),
1111
- parentSig->getGenericParams ().end ());
1113
+ GenericSignature *sig;
1114
+ if (!ext || ext->getTrailingWhereClause () ||
1115
+ getExtendedTypeGenericDepth (ext) != genericParams->getDepth ()) {
1116
+ // Collect the generic parameters.
1117
+ SmallVector<GenericTypeParamType *, 4 > allGenericParams;
1118
+ if (recursivelyVisitGenericParams) {
1119
+ visitOuterToInner (genericParams,
1120
+ [&](GenericParamList *gpList) {
1121
+ addGenericParamTypes (gpList, allGenericParams);
1122
+ });
1123
+ } else {
1124
+ if (parentSig) {
1125
+ allGenericParams.append (parentSig->getGenericParams ().begin (),
1126
+ parentSig->getGenericParams ().end ());
1127
+ }
1128
+
1129
+ addGenericParamTypes (genericParams, allGenericParams);
1112
1130
}
1113
1131
1114
- addGenericParamTypes (genericParams, allGenericParams);
1115
- }
1132
+ // Create the generic signature builder.
1133
+ GenericSignatureBuilder builder (Context, LookUpConformance (* this , dc));
1116
1134
1117
- // Create the generic signature builder.
1118
- ModuleDecl *module = dc->getParentModule ();
1119
- GenericSignatureBuilder builder (Context, LookUpConformance (*this , dc));
1135
+ // Type check the generic parameters, treating all generic type
1136
+ // parameters as dependent, unresolved.
1137
+ DependentGenericTypeResolver dependentResolver;
1138
+ if (recursivelyVisitGenericParams) {
1139
+ visitOuterToInner (genericParams,
1140
+ [&](GenericParamList *gpList) {
1141
+ checkGenericParamList (&builder, gpList, nullptr , &dependentResolver);
1142
+ });
1143
+ } else {
1144
+ checkGenericParamList (&builder, genericParams, parentSig,
1145
+ &dependentResolver);
1146
+ }
1120
1147
1121
- // Type check the generic parameters, treating all generic type
1122
- // parameters as dependent, unresolved.
1123
- DependentGenericTypeResolver dependentResolver;
1124
- if (recursivelyVisitGenericParams) {
1125
- visitOuterToInner (genericParams,
1126
- [&](GenericParamList *gpList) {
1127
- checkGenericParamList (&builder, gpList, nullptr , &dependentResolver);
1128
- });
1129
- } else {
1130
- checkGenericParamList (&builder, genericParams, parentSig,
1131
- &dependentResolver);
1132
- }
1148
+ // / Perform any necessary requirement inference.
1149
+ inferRequirements (builder);
1133
1150
1134
- // / Perform any necessary requirement inference.
1135
- inferRequirements (builder);
1151
+ // Finalize the generic requirements.
1152
+ (void )builder.finalize (genericParams->getSourceRange ().Start ,
1153
+ allGenericParams,
1154
+ allowConcreteGenericParams);
1136
1155
1137
- // Finalize the generic requirements.
1138
- (void )builder.finalize (genericParams->getSourceRange ().Start ,
1139
- allGenericParams,
1140
- allowConcreteGenericParams);
1156
+ // The generic signature builder now has all of the requirements, although
1157
+ // there might still be errors that have not yet been diagnosed. Revert the
1158
+ // signature and type-check it again, completely.
1159
+ if (recursivelyVisitGenericParams) {
1160
+ visitOuterToInner (genericParams,
1161
+ [&](GenericParamList *gpList) {
1162
+ revertGenericParamList (gpList);
1163
+ });
1164
+ } else {
1165
+ revertGenericParamList (genericParams);
1166
+ }
1141
1167
1142
- // The generic signature builder now has all of the requirements, although
1143
- // there might still be errors that have not yet been diagnosed. Revert the
1144
- // signature and type-check it again, completely.
1145
- if (recursivelyVisitGenericParams) {
1146
- visitOuterToInner (genericParams,
1147
- [&](GenericParamList *gpList) {
1148
- revertGenericParamList (gpList);
1149
- });
1150
- } else {
1151
- revertGenericParamList (genericParams);
1152
- }
1168
+ // Record the generic type parameter types and the requirements.
1169
+ sig = builder.getGenericSignature ();
1153
1170
1154
- // Record the generic type parameter types and the requirements.
1155
- auto sig = builder.getGenericSignature ();
1156
-
1157
- // Debugging of the generic signature builder and generic signature
1158
- // generation.
1159
- if (Context.LangOpts .DebugGenericSignatures ) {
1160
- dc->printContext (llvm::errs ());
1161
- llvm::errs () << " \n " ;
1162
- builder.dump (llvm::errs ());
1163
- llvm::errs () << " Generic signature: " ;
1164
- sig->print (llvm::errs ());
1165
- llvm::errs () << " \n " ;
1166
- llvm::errs () << " Canonical generic signature: " ;
1167
- sig->getCanonicalSignature ()->print (llvm::errs ());
1168
- llvm::errs () << " \n " ;
1171
+ // Debugging of the generic signature builder and generic signature
1172
+ // generation.
1173
+ if (Context.LangOpts .DebugGenericSignatures ) {
1174
+ dc->printContext (llvm::errs ());
1175
+ llvm::errs () << " \n " ;
1176
+ builder.dump (llvm::errs ());
1177
+ llvm::errs () << " Generic signature: " ;
1178
+ sig->print (llvm::errs ());
1179
+ llvm::errs () << " \n " ;
1180
+ llvm::errs () << " Canonical generic signature: " ;
1181
+ sig->getCanonicalSignature ()->print (llvm::errs ());
1182
+ llvm::errs () << " \n " ;
1183
+ }
1184
+ } else {
1185
+ // Re-use the signature of the type being extended.
1186
+ sig = ext->getAsNominalTypeOrNominalTypeExtensionContext ()
1187
+ ->getGenericSignatureOfContext ();
1169
1188
}
1170
1189
1171
1190
CompleteGenericTypeResolver completeResolver (*this , sig,
@@ -1181,6 +1200,7 @@ GenericEnvironment *TypeChecker::checkGenericEnvironment(
1181
1200
}
1182
1201
1183
1202
// Form the generic environment.
1203
+ ModuleDecl *module = dc->getParentModule ();
1184
1204
return sig->createGenericEnvironment (*module );
1185
1205
}
1186
1206
@@ -1205,8 +1225,10 @@ void TypeChecker::validateGenericTypeSignature(GenericTypeDecl *typeDecl) {
1205
1225
proto->computeRequirementSignature ();
1206
1226
}
1207
1227
1208
- auto *env = checkGenericEnvironment (gp, dc, dc->getGenericSignatureOfContext (),
1209
- /* allowConcreteGenericParams=*/ false );
1228
+ auto *env = checkGenericEnvironment (gp, dc,
1229
+ dc->getGenericSignatureOfContext (),
1230
+ /* allowConcreteGenericParams=*/ false ,
1231
+ /* ext=*/ nullptr );
1210
1232
typeDecl->setGenericEnvironment (env);
1211
1233
}
1212
1234
0 commit comments