mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix issues with runtime reporting incorrect types for nested generics
Fixes: https://github.com/apple/swift/issues/60565
This commit is contained in:
@@ -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())
|
||||
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(
|
||||
node->getFirstChild(), decl, --shapeIndex, args, argsIndex + numGenericArgs);
|
||||
parentNode, decl, --shapeIndex, args, argsIndex + numGenericArgs);
|
||||
}
|
||||
|
||||
return BoundGenericTypeRef::create(*this, mangling.result(), genericParams,
|
||||
parent);
|
||||
|
||||
@@ -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,12 +2923,13 @@ private:
|
||||
return decl;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T = BuilderType,
|
||||
template <typename T = BuilderType,
|
||||
typename std::enable_if_t<
|
||||
std::is_same<
|
||||
bool,
|
||||
decltype(T::needsToPrecomputeParentGenericContextShapes)>::value,
|
||||
const bool,
|
||||
decltype(T::needsToPrecomputeParentGenericContextShapes)>::
|
||||
value &&
|
||||
T::needsToPrecomputeParentGenericContextShapes,
|
||||
bool> = true>
|
||||
BuiltTypeDecl buildNominalTypeDecl(ContextDescriptorRef descriptor) {
|
||||
// Build the demangling tree from the context tree.
|
||||
@@ -2944,12 +2947,17 @@ private:
|
||||
countLevels(parentContext, runningCount);
|
||||
|
||||
auto genericContext = current->getGenericContext();
|
||||
if (!genericContext)
|
||||
return;
|
||||
// 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);
|
||||
|
||||
@@ -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: (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: (bound_generic_class reflect_nested.OuterGeneric.Inner
|
||||
// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterGeneric
|
||||
// CHECK-32-NEXT: (struct Swift.Int))))
|
||||
|
||||
doneReflecting()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user