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.
This commit is contained in:
Joe Groff
2018-04-05 16:22:31 -07:00
parent 9793439356
commit b51d43377e
2 changed files with 30 additions and 2 deletions

View File

@@ -747,8 +747,20 @@ public:
// Figure out the various levels of generic parameters we have in
// this type.
std::vector<unsigned> genericParamCounts;
bool innermostIsGeneric =
_gatherGenericParameterCounts(typeDecl, genericParamCounts);
bool innermostIsGeneric;
// If we have no parent given, try to form the whole type in one go.
if (!parent) {
innermostIsGeneric = !genericArgs.empty();
if (innermostIsGeneric) {
genericParamCounts.push_back(genericArgs.size());
}
// Otherwise, we'll need to steal the generic arguments from the parent
// type to build a nested type.
} else {
innermostIsGeneric = _gatherGenericParameterCounts(typeDecl,
genericParamCounts);
}
bool isGeneric = !genericParamCounts.empty();
// Gather the generic arguments.

View File

@@ -782,4 +782,20 @@ mirrors.test("String.init") {
expectEqual("42", String(reflecting: 42))
expectEqual("\"42\"", String(reflecting: "42"))
}
struct a<b> {
enum c{}
}
class d {}
struct e<f> {
var constraints: [Int: a<f>.c] = [:]
}
mirrors.test("field with generic nested type") {
let x = e<d>()
expectTrue(type(of: Mirror(reflecting: x).children.first!.value)
== [Int: a<d>.c].self)
}
runAllTests()