Skip to content

Commit 5e65e3e

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 0974006 commit 5e65e3e

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
@@ -2833,6 +2833,11 @@ class OpaqueTypeDecl : public GenericTypeDecl {
28332833

28342834
ValueDecl *getNamingDecl() const { return NamingDecl; }
28352835

2836+
void setNamingDecl(ValueDecl *D) {
2837+
assert(!NamingDecl && "already have naming decl");
2838+
NamingDecl = D;
2839+
}
2840+
28362841
GenericSignature *getOpaqueInterfaceGenericSignature() const {
28372842
return OpaqueInterfaceGenericSignature;
28382843
}

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;
@@ -3168,7 +3169,6 @@ class swift::DeclDeserializer {
31683169
interfaceTypeID, genericEnvID,
31693170
underlyingTypeID);
31703171

3171-
auto namingDecl = cast<ValueDecl>(MF.getDecl(namingDeclID));
31723172
auto declContext = MF.getDeclContext(contextID);
31733173
auto sig = MF.getGenericSignature(interfaceSigID);
31743174
auto interfaceType = MF.getType(interfaceTypeID)
@@ -3180,10 +3180,13 @@ class swift::DeclDeserializer {
31803180

31813181
// Create the decl.
31823182
auto opaqueDecl =
3183-
new (ctx) OpaqueTypeDecl(namingDecl, nullptr, declContext,
3183+
new (ctx) OpaqueTypeDecl(nullptr, nullptr, declContext,
31843184
sig, interfaceType);
31853185
declOrOffset = opaqueDecl;
31863186

3187+
auto namingDecl = cast<ValueDecl>(MF.getDecl(namingDeclID));
3188+
opaqueDecl->setNamingDecl(namingDecl);
3189+
31873190
if (auto genericParams = MF.maybeReadGenericParams(opaqueDecl))
31883191
opaqueDecl->setGenericParams(genericParams);
31893192

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)