Skip to content

Commit b51d433

Browse files
committed
Runtime: Properly handle demangling nested generic typerefs with symbolic manglings.
The demangling tree for a symbolic reference doesn't indicate the generic context depth of the referenced type, so we have to form the type metadata from whole cloth without incrementally building up nested types as we do for concrete mangled types. Notice when DecodedMetadataBuilder is passed a context descriptor ref without a parent and directly form the entire type in this case. Fixes rdar://problem/38891999.
1 parent 9793439 commit b51d433

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,20 @@ class DecodedMetadataBuilder {
747747
// Figure out the various levels of generic parameters we have in
748748
// this type.
749749
std::vector<unsigned> genericParamCounts;
750-
bool innermostIsGeneric =
751-
_gatherGenericParameterCounts(typeDecl, genericParamCounts);
750+
bool innermostIsGeneric;
751+
752+
// If we have no parent given, try to form the whole type in one go.
753+
if (!parent) {
754+
innermostIsGeneric = !genericArgs.empty();
755+
if (innermostIsGeneric) {
756+
genericParamCounts.push_back(genericArgs.size());
757+
}
758+
// Otherwise, we'll need to steal the generic arguments from the parent
759+
// type to build a nested type.
760+
} else {
761+
innermostIsGeneric = _gatherGenericParameterCounts(typeDecl,
762+
genericParamCounts);
763+
}
752764
bool isGeneric = !genericParamCounts.empty();
753765

754766
// Gather the generic arguments.

test/stdlib/Mirror.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,4 +782,20 @@ mirrors.test("String.init") {
782782
expectEqual("42", String(reflecting: 42))
783783
expectEqual("\"42\"", String(reflecting: "42"))
784784
}
785+
786+
struct a<b> {
787+
enum c{}
788+
}
789+
class d {}
790+
struct e<f> {
791+
var constraints: [Int: a<f>.c] = [:]
792+
}
793+
794+
mirrors.test("field with generic nested type") {
795+
let x = e<d>()
796+
797+
expectTrue(type(of: Mirror(reflecting: x).children.first!.value)
798+
== [Int: a<d>.c].self)
799+
}
800+
785801
runAllTests()

0 commit comments

Comments
 (0)