@@ -402,6 +402,38 @@ _findExtendedTypeContextDescriptor(const ContextDescriptor *maybeExtension,
402
402
Demangle::NodePointer &node = demangledNode ? *demangledNode : localNode;
403
403
404
404
auto mangledName = extension->getMangledExtendedContext ();
405
+
406
+ // A extension of the form `extension Protocol where Self == ConcreteType`
407
+ // is formally a protocol extension, so the formal generic parameter list
408
+ // is `<Self>`, but because of the same type constraint, the extended context
409
+ // looks like a reference to that nominal type. We want to match the
410
+ // extension's formal generic environment rather than the nominal type's
411
+ // in this case, so we should skip out on this case.
412
+ //
413
+ // We can detect this by looking at whether the generic context of the
414
+ // extension has a first generic parameter, which would be the Self parameter,
415
+ // with a same type constraint matching the extended type.
416
+ for (auto &reqt : extension->getGenericRequirements ()) {
417
+ if (reqt.getKind () != GenericRequirementKind::SameType) {
418
+ continue ;
419
+ }
420
+ // 'x' is the mangling of the first generic parameter
421
+ if (!reqt.getParam ().equals (" x" )) {
422
+ continue ;
423
+ }
424
+ // Is the generic parameter same-type-constrained to the same type
425
+ // we're extending? Then this is a `Self == ExtendedType` constraint.
426
+ // This is impossible for normal generic nominal type extensions because
427
+ // that would mean that you had:
428
+ // struct Foo<T> {...}
429
+ // extension Foo where T == Foo<T> {...}
430
+ // which would mean that the extended type is the infinite expansion
431
+ // Foo<Foo<Foo<Foo<...>>>>, which we don't allow.
432
+ if (reqt.getMangledTypeName ().data () == mangledName.data ()) {
433
+ return nullptr ;
434
+ }
435
+ }
436
+
405
437
node = demangler.demangleType (mangledName,
406
438
ResolveAsSymbolicReference (demangler));
407
439
if (!node)
@@ -1254,7 +1286,8 @@ _gatherGenericParameters(const ContextDescriptor *context,
1254
1286
(void )_gatherGenericParameterCounts (context,
1255
1287
genericParamCounts, demangler);
1256
1288
unsigned numTotalGenericParams =
1257
- genericParamCounts.empty () ? 0 : genericParamCounts.back ();
1289
+ genericParamCounts.empty () ? context->getNumGenericParams ()
1290
+ : genericParamCounts.back ();
1258
1291
1259
1292
// Check whether we have the right number of generic arguments.
1260
1293
if (genericArgs.size () == getLocalGenericParams (context).size ()) {
0 commit comments