@@ -1156,6 +1156,35 @@ PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
1156
1156
return anchor;
1157
1157
}
1158
1158
1159
+ namespace {
1160
+ // / Function object to diagnose a conflict in same-type constraints for a
1161
+ // / given potential archetype.
1162
+ struct DiagnoseSameTypeConflict {
1163
+ DiagnosticEngine &diags;
1164
+ const RequirementSource *source;
1165
+ PotentialArchetype *pa;
1166
+
1167
+ void operator ()(Type type1, Type type2) const {
1168
+ if (pa->getParent () && pa->getTypeAliasDecl () &&
1169
+ source->getLoc ().isInvalid ()) {
1170
+ diags.diagnose (pa->getTypeAliasDecl ()->getLoc (),
1171
+ diag::protocol_typealias_conflict,
1172
+ pa->getTypeAliasDecl ()->getName (),
1173
+ type1, type2);
1174
+ return ;
1175
+ }
1176
+
1177
+ if (source->getLoc ().isValid ()) {
1178
+ diags.diagnose (source->getLoc (),
1179
+ diag::requires_same_type_conflict,
1180
+ pa->isGenericParam (),
1181
+ pa->getDependentType (/* FIXME: */ { }, true ),
1182
+ type1, type2);
1183
+ }
1184
+ }
1185
+ };
1186
+ }
1187
+
1159
1188
// Give a nested type the appropriately resolved concrete type, based off a
1160
1189
// parent PA that has a concrete type.
1161
1190
static void concretizeNestedTypeFromConcreteParent (
@@ -1190,14 +1219,10 @@ static void concretizeNestedTypeFromConcreteParent(
1190
1219
}
1191
1220
1192
1221
builder.addSameTypeRequirement (nestedPA, witnessType, source,
1193
- [&](Type type1, Type type2) {
1194
- builder.getASTContext ().Diags .diagnose (
1195
- source->getLoc (),
1196
- diag::requires_same_type_conflict,
1197
- nestedPA->isGenericParam (),
1198
- nestedPA->getDependentType (/* FIXME: */ { }, true ),
1199
- type1, type2);
1200
- });
1222
+ DiagnoseSameTypeConflict{
1223
+ builder.getASTContext ().Diags ,
1224
+ source, nestedPA
1225
+ });
1201
1226
}
1202
1227
1203
1228
PotentialArchetype *PotentialArchetype::getNestedType (
@@ -1439,24 +1464,6 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
1439
1464
if (shouldUpdatePA) {
1440
1465
// For typealiases, introduce a same-type requirement to the aliased type.
1441
1466
if (typealias) {
1442
- auto diagnoseMismatch = [&](Type first, Type second) {
1443
- if (auto NAT = dyn_cast<NameAliasType>(first.getPointer ())) {
1444
- if (NAT->getDecl () == typealias) {
1445
- // If we have typealias T = Foo and Foo is completely concrete
1446
- // (e.g. Array<Int?>), then the subst will leave the NameAliasType
1447
- // intact. However, this means, if there's a
1448
- // concrete-type-mismatch at the top level, the default error
1449
- // message will be "ProtocolName.T (aka Foo)", but the "T" bit is
1450
- // already in the error message so it's better to print only
1451
- // "Foo".
1452
- first = NAT->getSinglyDesugaredType ();
1453
- }
1454
- }
1455
- builder.Diags .diagnose (typealias->getLoc (),
1456
- diag::protocol_typealias_conflict,
1457
- typealias->getName (), first, second);
1458
- };
1459
-
1460
1467
// FIXME (recursive decl validation): if the alias doesn't have an
1461
1468
// interface type when getNestedType is called while building a
1462
1469
// protocol's generic signature (i.e. during validation), then it'll
@@ -1481,8 +1488,7 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
1481
1488
builder.addSameTypeRequirement (
1482
1489
ResolvedType::forNewTypeAlias (resultPA),
1483
1490
builder.resolve (type),
1484
- RequirementSource::forNestedTypeNameMatch (resultPA),
1485
- diagnoseMismatch);
1491
+ RequirementSource::forNestedTypeNameMatch (resultPA));
1486
1492
}
1487
1493
}
1488
1494
@@ -2229,14 +2235,9 @@ bool GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
2229
2235
2230
2236
// FIXME: This seems early.
2231
2237
if (concrete1 && concrete2) {
2232
- bool mismatch = addSameTypeRequirement (
2233
- concrete1, concrete2, Source, [&](Type type1, Type type2) {
2234
- Diags.diagnose (Source->getLoc (),
2235
- diag::requires_same_type_conflict,
2236
- T1->isGenericParam (),
2237
- T1->getDependentType (/* FIXME: */ { }, true ), type1,
2238
- type2);
2239
- });
2238
+ bool mismatch = addSameTypeRequirement (concrete1, concrete2, Source,
2239
+ DiagnoseSameTypeConflict{
2240
+ Diags, Source, T1});
2240
2241
2241
2242
if (mismatch) return true ;
2242
2243
}
@@ -2315,13 +2316,7 @@ bool GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
2315
2316
if (addSameTypeRequirement (
2316
2317
T1Nested, T2Nested.second .front (),
2317
2318
RequirementSource::forNestedTypeNameMatch (T1Nested),
2318
- [&](Type type1, Type type2) {
2319
- Diags.diagnose (Source->getLoc (),
2320
- diag::requires_same_type_conflict,
2321
- T1Nested->isGenericParam (),
2322
- T1Nested->getDependentType (/* FIXME: */ { }, true ),
2323
- type1, type2);
2324
- }))
2319
+ DiagnoseSameTypeConflict{Diags, Source, T1Nested}))
2325
2320
return true ;
2326
2321
}
2327
2322
}
@@ -2342,16 +2337,10 @@ bool GenericSignatureBuilder::addSameTypeRequirementToConcrete(
2342
2337
2343
2338
// If we've already been bound to a type, match that type.
2344
2339
if (equivClass->concreteType ) {
2345
- bool mismatch = addSameTypeRequirement (
2346
- equivClass->concreteType , Concrete, Source,
2347
- [&](Type type1, Type type2) {
2348
- Diags.diagnose (Source->getLoc (),
2349
- diag::requires_same_type_conflict,
2350
- T->isGenericParam (),
2351
- T->getDependentType (/* FIXME: */ { }, true ), type1,
2352
- type2);
2353
-
2354
- });
2340
+ bool mismatch = addSameTypeRequirement (equivClass->concreteType , Concrete,
2341
+ Source,
2342
+ DiagnoseSameTypeConflict{
2343
+ Diags, Source, T});
2355
2344
2356
2345
if (mismatch) return true ;
2357
2346
0 commit comments