Skip to content

Commit 70aba4d

Browse files
committed
Serialization: Deserialize opaque type xrefs from the right extension module.
When deserializing an opaque type xref inside an extension context, we were looking incorrectly in the base module of the type being extended, rather than in the module of the extension, where the opaque type would really be. Fixes rdar://problem/51775500. This includes a small refactoring of OpaqueTypeDecl deserialization to break the inevitable cycle between deserializing the namingDecl, and the namingDecl turning around and re- deserializing its opaque return type. This is NFC but avoids some unnecessary work.
1 parent 83f86f5 commit 70aba4d

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,6 +2853,11 @@ class OpaqueTypeDecl : public GenericTypeDecl {
28532853

28542854
ValueDecl *getNamingDecl() const { return NamingDecl; }
28552855

2856+
void setNamingDecl(ValueDecl *D) {
2857+
assert(!NamingDecl && "already have naming decl");
2858+
NamingDecl = D;
2859+
}
2860+
28562861
GenericSignature *getOpaqueInterfaceGenericSignature() const {
28572862
return OpaqueInterfaceGenericSignature;
28582863
}

lib/Serialization/Deserialization.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,9 +1724,10 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
17241724

17251725
auto name = getIdentifier(DefiningDeclNameID);
17261726
pathTrace.addOpaqueReturnType(name);
1727-
1728-
if (auto opaqueTy = baseModule->lookupOpaqueResultType(name.str(),
1729-
nullptr)) {
1727+
1728+
auto lookupModule = M ? M : baseModule;
1729+
if (auto opaqueTy = lookupModule->lookupOpaqueResultType(name.str(),
1730+
nullptr)) {
17301731
values.push_back(opaqueTy);
17311732
}
17321733
break;
@@ -3134,7 +3135,6 @@ class swift::DeclDeserializer {
31343135
interfaceTypeID, genericEnvID,
31353136
underlyingTypeID);
31363137

3137-
auto namingDecl = cast<ValueDecl>(MF.getDecl(namingDeclID));
31383138
auto declContext = MF.getDeclContext(contextID);
31393139
auto sig = MF.getGenericSignature(interfaceSigID);
31403140
auto interfaceType = MF.getType(interfaceTypeID)
@@ -3146,10 +3146,13 @@ class swift::DeclDeserializer {
31463146

31473147
// Create the decl.
31483148
auto opaqueDecl =
3149-
new (ctx) OpaqueTypeDecl(namingDecl, nullptr, declContext,
3149+
new (ctx) OpaqueTypeDecl(nullptr, nullptr, declContext,
31503150
sig, interfaceType);
31513151
declOrOffset = opaqueDecl;
31523152

3153+
auto namingDecl = cast<ValueDecl>(MF.getDecl(namingDeclID));
3154+
opaqueDecl->setNamingDecl(namingDecl);
3155+
31533156
if (auto genericParams = MF.maybeReadGenericParams(opaqueDecl))
31543157
opaqueDecl->setGenericParams(genericParams);
31553158

test/SIL/Serialization/Inputs/OpaqueReturnTypeExporter.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@ public protocol Butt {}
22
extension Int: Butt {}
33

44
public func exportsOpaqueReturn() -> some Butt { return 0 }
5+
6+
extension Int {
7+
public func someButt() -> some Butt {
8+
return self
9+
}
10+
}

test/SIL/Serialization/opaque_return_type_serialize.sil

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,27 @@
33
// RUN: %target-sil-opt -I %t %s -emit-sib -module-name test -o %t/test.sib
44
// RUN: %target-swift-frontend -disable-availability-checking -I %t -emit-ir %t/test.sib
55

6+
import Swift
67
import OpaqueReturnTypeExporter
78

89
typealias SomeButt = @_opaqueReturnTypeOf("$s24OpaqueReturnTypeExporter07exportsaB0QryF", 0) opaque
10+
typealias SomeButt2 = @_opaqueReturnTypeOf("$sSi24OpaqueReturnTypeExporterE8someButtQryF", 0) opaque
911

1012
sil @$s24OpaqueReturnTypeExporter07exportsaB0QryF : $@convention(thin) () -> @out SomeButt
13+
sil @$sSi24OpaqueReturnTypeExporterE8someButtQryF : $@convention(thin) (Int) -> @out SomeButt2
1114

12-
sil @use_opaque_type : $@convention(thin) () -> () {
13-
entry:
15+
sil @use_opaque_type : $@convention(thin) (Int) -> () {
16+
entry(%a : $Int):
1417
%f = function_ref @$s24OpaqueReturnTypeExporter07exportsaB0QryF : $@convention(thin) () -> @out SomeButt
1518
%x = alloc_stack $SomeButt
1619
apply %f(%x) : $@convention(thin) () -> @out SomeButt
1720
destroy_addr %x : $*SomeButt
1821
dealloc_stack %x : $*SomeButt
22+
23+
%g = function_ref @$sSi24OpaqueReturnTypeExporterE8someButtQryF : $@convention(thin) (Int) -> @out SomeButt2
24+
%y = alloc_stack $SomeButt2
25+
apply %g(%y, %a) : $@convention(thin) (Int) -> @out SomeButt2
26+
destroy_addr %y : $*SomeButt2
27+
dealloc_stack %y : $*SomeButt2
1928
return undef : $()
2029
}

0 commit comments

Comments
 (0)