Skip to content

Commit 893d83b

Browse files
committed
Fix wrong calculation of generic params per level when building decl
Fix computation of generic params per level when a generic type is nested in a non-generic one. For example, for the following code: ``` class A { class B<T, U> { } } ``` Fix the array of generic params per level from [2] to [0, 2]. rdar://103457629
1 parent 382510f commit 893d83b

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

include/swift/Remote/MetadataReader.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,13 +2953,19 @@ class MetadataReader {
29532953
// Only consider generic contexts of type class, enum or struct.
29542954
// There are other context types that can be generic, but they should
29552955
// not affect the generic shape.
2956-
if (genericContext &&
2957-
(current->getKind() == ContextDescriptorKind::Class ||
2958-
current->getKind() == ContextDescriptorKind::Enum ||
2959-
current->getKind() == ContextDescriptorKind::Struct)) {
2960-
auto contextHeader = genericContext->getGenericContextHeader();
2961-
paramsPerLevel.emplace_back(contextHeader.NumParams - runningCount);
2962-
runningCount += paramsPerLevel.back();
2956+
if (current->getKind() == ContextDescriptorKind::Class ||
2957+
current->getKind() == ContextDescriptorKind::Enum ||
2958+
current->getKind() == ContextDescriptorKind::Struct) {
2959+
if (genericContext) {
2960+
auto contextHeader = genericContext->getGenericContextHeader();
2961+
paramsPerLevel.emplace_back(contextHeader.NumParams -
2962+
runningCount);
2963+
runningCount += paramsPerLevel.back();
2964+
} else {
2965+
// If there is no generic context, this is a non-generic type
2966+
// which has 0 generic parameters.
2967+
paramsPerLevel.emplace_back(0);
2968+
}
29632969
}
29642970
};
29652971
countLevels(descriptor, runningCount);

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,9 +596,13 @@ class TypeRefBuilder {
596596
break;
597597
}
598598
}
599-
if (parentNode)
600-
parent = createBoundGenericTypeReconstructingParent(
601-
parentNode, decl, --shapeIndex, args, argsIndex + numGenericArgs);
599+
if (parentNode) {
600+
if (shapeIndex > 0)
601+
parent = createBoundGenericTypeReconstructingParent(
602+
parentNode, decl, --shapeIndex, args, argsIndex + numGenericArgs);
603+
else
604+
return nullptr;
605+
}
602606
}
603607

604608
return BoundGenericTypeRef::create(*this, mangling.result(), genericParams,

validation-test/Reflection/reflect_nested.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,37 @@ reflect(object: obj)
4343
// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterGeneric.Inner
4444
// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterGeneric
4545
// CHECK-32-NEXT: (struct Swift.Int))))
46+
47+
class OuterNonGeneric {
48+
class InnerGeneric<T, U> {
49+
var x: T
50+
var y: U
51+
52+
init(x: T, y: U) {
53+
self.x = x
54+
self.y = y
55+
}
56+
}
57+
}
58+
59+
var obj2 = OuterNonGeneric.InnerGeneric(x: 17, y: "hello")
60+
reflect(object: obj2)
61+
62+
// CHECK-64: Reflecting an object.
63+
// CHECK-64: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
64+
// CHECK-64: Type reference:
65+
// CHECK-64: (bound_generic_class reflect_nested.OuterNonGeneric.InnerGeneric
66+
// CHECK-64-NEXT: (struct Swift.Int)
67+
// CHECK-64-NEXT: (struct Swift.String)
68+
// CHECK-64-NEXT: (bound_generic_class reflect_nested.OuterNonGeneric))
69+
70+
// CHECK-32: Reflecting an object.
71+
// CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
72+
// CHECK-32: Type reference:
73+
// CHECK-32: (bound_generic_class reflect_nested.OuterNonGeneric.InnerGeneric
74+
// CHECK-32-NEXT: (struct Swift.Int)
75+
// CHECK-32-NEXT: (struct Swift.String)
76+
// CHECK-32-NEXT: (bound_generic_class reflect_nested.OuterNonGeneric))
4677

4778
doneReflecting()
4879

0 commit comments

Comments
 (0)