Skip to content

Commit d6a5570

Browse files
authored
Merge pull request swiftlang#27929 from xymus/deser-custom-attr
[serialization] Recover from missing custom attribute
2 parents 64401ac + ac28905 commit d6a5570

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2727,7 +2727,19 @@ class swift::DeclDeserializer {
27272727

27282728
// If there are any backing properties, record them.
27292729
if (numBackingProperties > 0) {
2730-
VarDecl *backingVar = cast<VarDecl>(MF.getDecl(backingPropertyIDs[0]));
2730+
auto backingDecl = MF.getDeclChecked(backingPropertyIDs[0]);
2731+
if (!backingDecl) {
2732+
if (numBackingProperties > 1 &&
2733+
backingDecl.errorIsA<XRefNonLoadedModuleError>()) {
2734+
// A property wrapper defined behind an implementation-only import
2735+
// is safe to drop when it can't be deserialized.
2736+
// rdar://problem/56599179
2737+
consumeError(backingDecl.takeError());
2738+
} else
2739+
return backingDecl.takeError();
2740+
}
2741+
2742+
VarDecl *backingVar = cast<VarDecl>(backingDecl.get());
27312743
VarDecl *storageWrapperVar = nullptr;
27322744
if (numBackingProperties > 1) {
27332745
storageWrapperVar = cast<VarDecl>(MF.getDecl(backingPropertyIDs[1]));
@@ -3873,6 +3885,7 @@ llvm::Error DeclDeserializer::deserializeDeclAttributes() {
38733885

38743886
if (isDeclAttrRecord(recordID)) {
38753887
DeclAttribute *Attr = nullptr;
3888+
bool skipAttr = false;
38763889
switch (recordID) {
38773890
case decls_block::SILGenName_DECL_ATTR: {
38783891
bool isImplicit;
@@ -4073,13 +4086,19 @@ llvm::Error DeclDeserializer::deserializeDeclAttributes() {
40734086

40744087
Expected<Type> deserialized = MF.getTypeChecked(typeID);
40754088
if (!deserialized) {
4076-
MF.fatal(deserialized.takeError());
4077-
break;
4089+
if (deserialized.errorIsA<XRefNonLoadedModuleError>()) {
4090+
// A custom attribute defined behind an implementation-only import
4091+
// is safe to drop when it can't be deserialized.
4092+
// rdar://problem/56599179
4093+
consumeError(deserialized.takeError());
4094+
skipAttr = true;
4095+
} else
4096+
return deserialized.takeError();
4097+
} else {
4098+
Attr = CustomAttr::create(ctx, SourceLoc(),
4099+
TypeLoc::withoutLoc(deserialized.get()),
4100+
isImplicit);
40784101
}
4079-
4080-
Attr = CustomAttr::create(ctx, SourceLoc(),
4081-
TypeLoc::withoutLoc(deserialized.get()),
4082-
isImplicit);
40834102
break;
40844103
}
40854104

@@ -4110,10 +4129,12 @@ llvm::Error DeclDeserializer::deserializeDeclAttributes() {
41104129
MF.fatal();
41114130
}
41124131

4113-
if (!Attr)
4114-
return llvm::Error::success();
4132+
if (!skipAttr) {
4133+
if (!Attr)
4134+
return llvm::Error::success();
41154135

4116-
AddAttribute(Attr);
4136+
AddAttribute(Attr);
4137+
}
41174138

41184139
} else if (recordID == decls_block::PRIVATE_DISCRIMINATOR) {
41194140
IdentifierID discriminatorID;

test/Serialization/Recovery/implementation-only-missing.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,23 @@
1313
//// private module is superfluous but makes sure that it's not somehow loaded.
1414
// RUN: rm %t/private_lib.swiftmodule
1515
// RUN: %target-swift-frontend -typecheck -DCLIENT_APP -primary-file %s -I %t -index-system-modules -index-store-path %t
16+
// RUN: %target-swift-frontend -emit-sil -DCLIENT_APP -primary-file %s -I %t -module-name client
1617

1718
#if PRIVATE_LIB
1819

20+
@propertyWrapper
21+
public struct IoiPropertyWrapper<V> {
22+
var content: V
23+
24+
public init(_ v: V) {
25+
content = v
26+
}
27+
28+
public var wrappedValue: V {
29+
return content
30+
}
31+
}
32+
1933
public struct HiddenGenStruct<A: HiddenProtocol> {
2034
public init() {}
2135
}
@@ -49,11 +63,18 @@ extension LibProtocol where TA == LibProtocolTA {
4963

5064
public struct PublicStruct: LibProtocol {
5165
typealias TA = LibProtocolTA
66+
5267
public init() { }
68+
69+
@IoiPropertyWrapper("some text")
70+
public var wrappedVar: String
5371
}
5472

5573
#elseif CLIENT_APP
5674

5775
import public_lib
5876

77+
var s = PublicStruct()
78+
print(s.wrappedVar)
79+
5980
#endif

0 commit comments

Comments
 (0)