Skip to content

Commit 9a411be

Browse files
committed
MetadataLookup: Use extension's generic context for non-nominal extensions
In protocol extensions, and in the future parameterized extensions, have their own generic arguments independent of an originating nominal type's formal generic parameters. Instead of crashing, handle this gracefully. rdar://problem/50038754
1 parent 1ed77dc commit 9a411be

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ _findExtendedTypeContextDescriptor(const ExtensionContextDescriptor *extension,
247247
return nullptr;
248248
node = node->getChild(0);
249249
}
250-
node = Demangle::getUnspecialized(node, demangler);
250+
if (Demangle::isSpecialized(node)) {
251+
node = Demangle::getUnspecialized(node, demangler);
252+
}
251253

252254
return _findNominalTypeDescriptor(node, demangler);
253255
}
@@ -823,15 +825,17 @@ bool swift::_gatherGenericParameterCounts(
823825
const ContextDescriptor *descriptor,
824826
SmallVectorImpl<unsigned> &genericParamCounts,
825827
Demangler &BorrowFrom) {
826-
// If we have an extension descriptor, extract the extended type and use
827-
// that.
828828
DemanglerForRuntimeTypeResolution<> demangler;
829829
demangler.providePreallocatedMemory(BorrowFrom);
830830

831831
if (auto extension = dyn_cast<ExtensionContextDescriptor>(descriptor)) {
832+
// If we have an nominal type extension descriptor, extract the extended type
833+
// and use that. If the extension is not nominal, then we can use the
834+
// extension's own signature.
832835
if (auto extendedType =
833-
_findExtendedTypeContextDescriptor(extension, demangler))
836+
_findExtendedTypeContextDescriptor(extension, demangler)) {
834837
descriptor = extendedType;
838+
}
835839
}
836840

837841
// Once we hit a non-generic descriptor, we're done.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-run-simple-swift | %FileCheck %s
2+
// REQUIRES: executable_test
3+
4+
protocol P {
5+
associatedtype AT
6+
func foo() -> AT
7+
}
8+
9+
extension P {
10+
func foo() -> some P {
11+
return self
12+
}
13+
}
14+
15+
func getPAT<T: P>(_: T.Type) -> Any.Type {
16+
return T.AT.self
17+
}
18+
19+
extension Int: P { }
20+
21+
// CHECK: Int
22+
print(getPAT(Int.self))

0 commit comments

Comments
 (0)