diff --git a/include/swift/Reflection/TypeRefBuilder.h b/include/swift/Reflection/TypeRefBuilder.h index 33ddfbb8ed5..0c8b1453f16 100644 --- a/include/swift/Reflection/TypeRefBuilder.h +++ b/include/swift/Reflection/TypeRefBuilder.h @@ -558,9 +558,7 @@ public: auto kind = node->getKind(); // Kinds who have a "BoundGeneric..." variant. if (kind != Node::Kind::Class && kind != Node::Kind::Structure && - kind != Node::Kind::Enum && kind != Node::Kind::Protocol && - kind != Node::Kind::OtherNominalType && kind != Node::Kind::TypeAlias && - kind != Node::Kind::Function) + kind != Node::Kind::Enum) return nullptr; auto mangling = Demangle::mangleNode(node); if (!mangling.isSuccess()) @@ -572,9 +570,23 @@ public: args.end() - argsIndex - numGenericArgs, args.end() - argsIndex); const BoundGenericTypeRef *parent = nullptr; - if (node->hasChildren()) - parent = createBoundGenericTypeReconstructingParent( - node->getFirstChild(), decl, --shapeIndex, args, argsIndex + numGenericArgs); + if (node->hasChildren()) { + // Skip over nodes that are not of type class, enum or struct + auto parentNode = node->getFirstChild(); + while (parentNode->getKind() != Node::Kind::Class && + parentNode->getKind() != Node::Kind::Structure && + parentNode->getKind() != Node::Kind::Enum) { + if (parentNode->hasChildren()) { + parentNode = parentNode->getFirstChild(); + } else { + parentNode = nullptr; + break; + } + } + if (parentNode) + parent = createBoundGenericTypeReconstructingParent( + parentNode, decl, --shapeIndex, args, argsIndex + numGenericArgs); + } return BoundGenericTypeRef::create(*this, mangling.result(), genericParams, parent); diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h index f23c911308f..c1faf54f89d 100644 --- a/include/swift/Remote/MetadataReader.h +++ b/include/swift/Remote/MetadataReader.h @@ -2906,9 +2906,11 @@ private: template < typename T = BuilderType, typename std::enable_if_t< - !std::is_same< - bool, - decltype(T::needsToPrecomputeParentGenericContextShapes)>::value, + !(std::is_same< + const bool, + decltype(T::needsToPrecomputeParentGenericContextShapes)>:: + value && + T::needsToPrecomputeParentGenericContextShapes), bool> = true> BuiltTypeDecl buildNominalTypeDecl(ContextDescriptorRef descriptor) { // Build the demangling tree from the context tree. @@ -2921,13 +2923,14 @@ private: return decl; } - template < - typename T = BuilderType, - typename std::enable_if_t< - std::is_same< - bool, - decltype(T::needsToPrecomputeParentGenericContextShapes)>::value, - bool> = true> + template :: + value && + T::needsToPrecomputeParentGenericContextShapes, + bool> = true> BuiltTypeDecl buildNominalTypeDecl(ContextDescriptorRef descriptor) { // Build the demangling tree from the context tree. Demangler dem; @@ -2944,12 +2947,17 @@ private: countLevels(parentContext, runningCount); auto genericContext = current->getGenericContext(); - if (!genericContext) - return; - auto contextHeader = genericContext->getGenericContextHeader(); - - paramsPerLevel.emplace_back(contextHeader.NumParams - runningCount); - runningCount += paramsPerLevel.back(); + // Only consider generic contexts of type class, enum or struct. + // There are other context types that can be generic, but they should + // not affect the generic shape. + if (genericContext && + (current->getKind() == ContextDescriptorKind::Class || + current->getKind() == ContextDescriptorKind::Enum || + current->getKind() == ContextDescriptorKind::Struct)) { + auto contextHeader = genericContext->getGenericContextHeader(); + paramsPerLevel.emplace_back(contextHeader.NumParams - runningCount); + runningCount += paramsPerLevel.back(); + } }; countLevels(descriptor, runningCount); BuiltTypeDecl decl = Builder.createTypeDecl(node, paramsPerLevel); diff --git a/validation-test/Reflection/reflect_nested.swift b/validation-test/Reflection/reflect_nested.swift index 90cbc1a3c33..a80060e8001 100644 --- a/validation-test/Reflection/reflect_nested.swift +++ b/validation-test/Reflection/reflect_nested.swift @@ -30,15 +30,19 @@ reflect(object: obj) // CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}} // CHECK-64: Type reference: // CHECK-64: (bound_generic_class reflect_nested.OuterGeneric.Inner.Innermost -// CHECK-64-NEXT: (struct Swift.Int) -// CHECK-64-NEXT: (struct Swift.String) +// CHECK-64-NEXT: (struct Swift.String) +// CHECK-64-NEXT: (bound_generic_class reflect_nested.OuterGeneric.Inner +// CHECK-64-NEXT: (bound_generic_class reflect_nested.OuterGeneric +// CHECK-64-NEXT: (struct Swift.Int)))) // CHECK-32: Reflecting an object. // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}} // CHECK-32: Type reference: // CHECK-32: (bound_generic_class reflect_nested.OuterGeneric.Inner.Innermost -// CHECK-32-NEXT: (struct Swift.Int) -// CHECK-32-NEXT: (struct Swift.String) +// CHECK-32-NEXT: (struct Swift.String) +// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterGeneric.Inner +// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterGeneric +// CHECK-32-NEXT: (struct Swift.Int)))) doneReflecting()