Skip to content

Commit 44af3a9

Browse files
authored
Merge pull request #26561 from jckarter/opaque-assoc-type-demangle-workaround
IRGen: Work around runtime bug demangling associated types of opaque types.
2 parents 178e755 + e6bc3e7 commit 44af3a9

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

lib/IRGen/MetadataRequest.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,6 +2015,19 @@ static bool shouldAccessByMangledName(IRGenModule &IGM, CanType type) {
20152015
}
20162016
}
20172017

2018+
// The Swift 5.1 runtime fails to demangle associated types of opaque types.
2019+
auto hasNestedOpaqueArchetype = type.findIf([](CanType sub) -> bool {
2020+
if (auto archetype = dyn_cast<NestedArchetypeType>(sub)) {
2021+
if (isa<OpaqueTypeArchetypeType>(archetype->getRoot())) {
2022+
return true;
2023+
}
2024+
}
2025+
return false;
2026+
});
2027+
2028+
if (hasNestedOpaqueArchetype)
2029+
return false;
2030+
20182031
return true;
20192032

20202033
// The visitor below can be used to fine-tune a heuristic to decide whether

test/Interpreter/opaque_return_type_protocol_ext.swift

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-run-simple-swift | %FileCheck %s
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -swift-version 5 %s -o %t/a.out
3+
// RUN: %target-run %t/a.out | %FileCheck %s
4+
25
// REQUIRES: executable_test
36

47
@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
@@ -39,3 +42,40 @@ if #available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *) {
3942
} else {
4043
print("i'm getting too old for this sh")
4144
}
45+
46+
// rdar://problem/54084733
47+
48+
protocol Q {
49+
associatedtype A
50+
func f() -> A
51+
}
52+
struct X: Q {
53+
typealias A = Array<Int>
54+
func f() -> A {
55+
return [1, 2, 3]
56+
}
57+
}
58+
@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
59+
dynamic func g() -> some Q {
60+
return X()
61+
}
62+
63+
func h<T: Q>(x: T) -> (T.A?, T.A?) {
64+
return (.some(x.f()), .some(x.f()))
65+
}
66+
67+
if #available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *) {
68+
let x = g()
69+
// CHECK: {{X()|no really}}
70+
print(x)
71+
// CHECK: {{[1, 2, 3]|too old}}
72+
let y = x.f()
73+
print(y)
74+
// CHECK: {{[1, 2, 3]|too old}}
75+
let z = h(x: x)
76+
print(z)
77+
} else {
78+
print("no really")
79+
print("i'm getting way too old for this sh")
80+
print("way too old")
81+
}

0 commit comments

Comments
 (0)