Skip to content

Commit 48604ca

Browse files
authored
Merge pull request #61819 from NuriAmari/remote-ast-runtime-type-mismatch
Fix issues with runtime reporting incorrect types for nested generics
2 parents 6402bde + 66f9931 commit 48604ca

File tree

3 files changed

+50
-26
lines changed

3 files changed

+50
-26
lines changed

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,7 @@ class TypeRefBuilder {
558558
auto kind = node->getKind();
559559
// Kinds who have a "BoundGeneric..." variant.
560560
if (kind != Node::Kind::Class && kind != Node::Kind::Structure &&
561-
kind != Node::Kind::Enum && kind != Node::Kind::Protocol &&
562-
kind != Node::Kind::OtherNominalType && kind != Node::Kind::TypeAlias &&
563-
kind != Node::Kind::Function)
561+
kind != Node::Kind::Enum)
564562
return nullptr;
565563
auto mangling = Demangle::mangleNode(node);
566564
if (!mangling.isSuccess())
@@ -572,9 +570,23 @@ class TypeRefBuilder {
572570
args.end() - argsIndex - numGenericArgs, args.end() - argsIndex);
573571

574572
const BoundGenericTypeRef *parent = nullptr;
575-
if (node->hasChildren())
576-
parent = createBoundGenericTypeReconstructingParent(
577-
node->getFirstChild(), decl, --shapeIndex, args, argsIndex + numGenericArgs);
573+
if (node->hasChildren()) {
574+
// Skip over nodes that are not of type class, enum or struct
575+
auto parentNode = node->getFirstChild();
576+
while (parentNode->getKind() != Node::Kind::Class &&
577+
parentNode->getKind() != Node::Kind::Structure &&
578+
parentNode->getKind() != Node::Kind::Enum) {
579+
if (parentNode->hasChildren()) {
580+
parentNode = parentNode->getFirstChild();
581+
} else {
582+
parentNode = nullptr;
583+
break;
584+
}
585+
}
586+
if (parentNode)
587+
parent = createBoundGenericTypeReconstructingParent(
588+
parentNode, decl, --shapeIndex, args, argsIndex + numGenericArgs);
589+
}
578590

579591
return BoundGenericTypeRef::create(*this, mangling.result(), genericParams,
580592
parent);

include/swift/Remote/MetadataReader.h

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2906,9 +2906,11 @@ class MetadataReader {
29062906
template <
29072907
typename T = BuilderType,
29082908
typename std::enable_if_t<
2909-
!std::is_same<
2910-
bool,
2911-
decltype(T::needsToPrecomputeParentGenericContextShapes)>::value,
2909+
!(std::is_same<
2910+
const bool,
2911+
decltype(T::needsToPrecomputeParentGenericContextShapes)>::
2912+
value &&
2913+
T::needsToPrecomputeParentGenericContextShapes),
29122914
bool> = true>
29132915
BuiltTypeDecl buildNominalTypeDecl(ContextDescriptorRef descriptor) {
29142916
// Build the demangling tree from the context tree.
@@ -2921,13 +2923,14 @@ class MetadataReader {
29212923
return decl;
29222924
}
29232925

2924-
template <
2925-
typename T = BuilderType,
2926-
typename std::enable_if_t<
2927-
std::is_same<
2928-
bool,
2929-
decltype(T::needsToPrecomputeParentGenericContextShapes)>::value,
2930-
bool> = true>
2926+
template <typename T = BuilderType,
2927+
typename std::enable_if_t<
2928+
std::is_same<
2929+
const bool,
2930+
decltype(T::needsToPrecomputeParentGenericContextShapes)>::
2931+
value &&
2932+
T::needsToPrecomputeParentGenericContextShapes,
2933+
bool> = true>
29312934
BuiltTypeDecl buildNominalTypeDecl(ContextDescriptorRef descriptor) {
29322935
// Build the demangling tree from the context tree.
29332936
Demangler dem;
@@ -2944,12 +2947,17 @@ class MetadataReader {
29442947
countLevels(parentContext, runningCount);
29452948

29462949
auto genericContext = current->getGenericContext();
2947-
if (!genericContext)
2948-
return;
2949-
auto contextHeader = genericContext->getGenericContextHeader();
2950-
2951-
paramsPerLevel.emplace_back(contextHeader.NumParams - runningCount);
2952-
runningCount += paramsPerLevel.back();
2950+
// Only consider generic contexts of type class, enum or struct.
2951+
// There are other context types that can be generic, but they should
2952+
// not affect the generic shape.
2953+
if (genericContext &&
2954+
(current->getKind() == ContextDescriptorKind::Class ||
2955+
current->getKind() == ContextDescriptorKind::Enum ||
2956+
current->getKind() == ContextDescriptorKind::Struct)) {
2957+
auto contextHeader = genericContext->getGenericContextHeader();
2958+
paramsPerLevel.emplace_back(contextHeader.NumParams - runningCount);
2959+
runningCount += paramsPerLevel.back();
2960+
}
29532961
};
29542962
countLevels(descriptor, runningCount);
29552963
BuiltTypeDecl decl = Builder.createTypeDecl(node, paramsPerLevel);

validation-test/Reflection/reflect_nested.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,19 @@ reflect(object: obj)
3030
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
3131
// CHECK-64: Type reference:
3232
// CHECK-64: (bound_generic_class reflect_nested.OuterGeneric.Inner.Innermost
33-
// CHECK-64-NEXT: (struct Swift.Int)
34-
// CHECK-64-NEXT: (struct Swift.String)
33+
// CHECK-64-NEXT: (struct Swift.String)
34+
// CHECK-64-NEXT: (bound_generic_class reflect_nested.OuterGeneric.Inner
35+
// CHECK-64-NEXT: (bound_generic_class reflect_nested.OuterGeneric
36+
// CHECK-64-NEXT: (struct Swift.Int))))
3537

3638
// CHECK-32: Reflecting an object.
3739
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
3840
// CHECK-32: Type reference:
3941
// CHECK-32: (bound_generic_class reflect_nested.OuterGeneric.Inner.Innermost
40-
// CHECK-32-NEXT: (struct Swift.Int)
41-
// CHECK-32-NEXT: (struct Swift.String)
42+
// CHECK-32-NEXT: (struct Swift.String)
43+
// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterGeneric.Inner
44+
// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterGeneric
45+
// CHECK-32-NEXT: (struct Swift.Int))))
4246

4347
doneReflecting()
4448

0 commit comments

Comments
 (0)