Skip to content

Commit

Permalink
[serialization] Recover from missing custom attribute
Browse files Browse the repository at this point in the history
rdar://problem/56599179
  • Loading branch information
xymus committed Oct 30, 2019
1 parent fd1a2a4 commit ac28905
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 10 deletions.
41 changes: 31 additions & 10 deletions lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2727,7 +2727,19 @@ class swift::DeclDeserializer {

// If there are any backing properties, record them.
if (numBackingProperties > 0) {
VarDecl *backingVar = cast<VarDecl>(MF.getDecl(backingPropertyIDs[0]));
auto backingDecl = MF.getDeclChecked(backingPropertyIDs[0]);
if (!backingDecl) {
if (numBackingProperties > 1 &&
backingDecl.errorIsA<XRefNonLoadedModuleError>()) {
// A property wrapper defined behind an implementation-only import
// is safe to drop when it can't be deserialized.
// rdar://problem/56599179
consumeError(backingDecl.takeError());
} else
return backingDecl.takeError();
}

VarDecl *backingVar = cast<VarDecl>(backingDecl.get());
VarDecl *storageWrapperVar = nullptr;
if (numBackingProperties > 1) {
storageWrapperVar = cast<VarDecl>(MF.getDecl(backingPropertyIDs[1]));
Expand Down Expand Up @@ -3873,6 +3885,7 @@ llvm::Error DeclDeserializer::deserializeDeclAttributes() {

if (isDeclAttrRecord(recordID)) {
DeclAttribute *Attr = nullptr;
bool skipAttr = false;
switch (recordID) {
case decls_block::SILGenName_DECL_ATTR: {
bool isImplicit;
Expand Down Expand Up @@ -4073,13 +4086,19 @@ llvm::Error DeclDeserializer::deserializeDeclAttributes() {

Expected<Type> deserialized = MF.getTypeChecked(typeID);
if (!deserialized) {
MF.fatal(deserialized.takeError());
break;
if (deserialized.errorIsA<XRefNonLoadedModuleError>()) {
// A custom attribute defined behind an implementation-only import
// is safe to drop when it can't be deserialized.
// rdar://problem/56599179
consumeError(deserialized.takeError());
skipAttr = true;
} else
return deserialized.takeError();
} else {
Attr = CustomAttr::create(ctx, SourceLoc(),
TypeLoc::withoutLoc(deserialized.get()),
isImplicit);
}

Attr = CustomAttr::create(ctx, SourceLoc(),
TypeLoc::withoutLoc(deserialized.get()),
isImplicit);
break;
}

Expand Down Expand Up @@ -4110,10 +4129,12 @@ llvm::Error DeclDeserializer::deserializeDeclAttributes() {
MF.fatal();
}

if (!Attr)
return llvm::Error::success();
if (!skipAttr) {
if (!Attr)
return llvm::Error::success();

AddAttribute(Attr);
AddAttribute(Attr);
}

} else if (recordID == decls_block::PRIVATE_DISCRIMINATOR) {
IdentifierID discriminatorID;
Expand Down
21 changes: 21 additions & 0 deletions test/Serialization/Recovery/implementation-only-missing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,23 @@
//// private module is superfluous but makes sure that it's not somehow loaded.
// RUN: rm %t/private_lib.swiftmodule
// RUN: %target-swift-frontend -typecheck -DCLIENT_APP -primary-file %s -I %t -index-system-modules -index-store-path %t
// RUN: %target-swift-frontend -emit-sil -DCLIENT_APP -primary-file %s -I %t -module-name client

#if PRIVATE_LIB

@propertyWrapper
public struct IoiPropertyWrapper<V> {
var content: V

public init(_ v: V) {
content = v
}

public var wrappedValue: V {
return content
}
}

public struct HiddenGenStruct<A: HiddenProtocol> {
public init() {}
}
Expand Down Expand Up @@ -49,11 +63,18 @@ extension LibProtocol where TA == LibProtocolTA {

public struct PublicStruct: LibProtocol {
typealias TA = LibProtocolTA

public init() { }

@IoiPropertyWrapper("some text")
public var wrappedVar: String
}

#elseif CLIENT_APP

import public_lib

var s = PublicStruct()
print(s.wrappedVar)

#endif

0 comments on commit ac28905

Please sign in to comment.