Skip to content

Commit e3207f7

Browse files
committed
[Serialization] Handle re-export of error enums mapped via import-as-member.
Thanks to Jordan for coming up with the right combination of features to trigger this code path.
1 parent fc20deb commit e3207f7

File tree

6 files changed

+34
-15
lines changed

6 files changed

+34
-15
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/PrettyStackTrace.h"
2525
#include "swift/AST/ProtocolConformance.h"
2626
#include "swift/ClangImporter/ClangImporter.h"
27+
#include "swift/ClangImporter/ClangModule.h"
2728
#include "swift/Serialization/BCReadingExtras.h"
2829
#include "swift/Serialization/SerializedModuleLoader.h"
2930
#include "swift/Basic/Defer.h"
@@ -1098,6 +1099,23 @@ getActualCtorInitializerKind(uint8_t raw) {
10981099
return None;
10991100
}
11001101

1102+
/// Determine whether the two modules are re-exported to the same module.
1103+
static bool reExportedToSameModule(const ModuleDecl *fromModule,
1104+
const ModuleDecl *toModule) {
1105+
auto fromClangModule
1106+
= dyn_cast<ClangModuleUnit>(fromModule->getFiles().front());
1107+
if (!fromClangModule)
1108+
return false;
1109+
1110+
auto toClangModule
1111+
= dyn_cast<ClangModuleUnit>(toModule->getFiles().front());
1112+
if (!toClangModule)
1113+
return false;
1114+
1115+
return fromClangModule->getExportedModuleName() ==
1116+
toClangModule->getExportedModuleName();
1117+
}
1118+
11011119
/// Remove values from \p values that don't match the expected type or module.
11021120
///
11031121
/// Any of \p expectedTy, \p expectedModule, or \p expectedGenericSig can be
@@ -1130,7 +1148,8 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
11301148
// FIXME: Should be able to move a value from an extension in a derived
11311149
// module to the original definition in a base module.
11321150
if (expectedModule && !value->hasClangNode() &&
1133-
value->getModuleContext() != expectedModule)
1151+
value->getModuleContext() != expectedModule &&
1152+
!reExportedToSameModule(value->getModuleContext(), expectedModule))
11341153
return true;
11351154

11361155
// If we're expecting a member within a constrained extension with a

lib/Serialization/Serialization.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "swift/ClangImporter/ClangModule.h"
3838
#include "swift/Serialization/SerializationOptions.h"
3939

40-
#include "clang/Basic/Module.h"
4140
// FIXME: We're just using CompilerInstance::createOutputFile.
4241
// This API should be sunk down to LLVM.
4342
#include "clang/Frontend/CompilerInstance.h"
@@ -533,13 +532,14 @@ IdentifierID Serializer::addModuleRef(const ModuleDecl *M) {
533532

534533
// If we're referring to a member of a private module that will be
535534
// re-exported via a public module, record the public module's name.
536-
if (auto clangModule = M->findUnderlyingClangModule()) {
537-
if (!clangModule->ExportAsModule.empty()) {
538-
auto publicModuleName =
539-
M->getASTContext().getIdentifier(clangModule->ExportAsModule);
540-
return addDeclBaseNameRef(publicModuleName);
541-
}
535+
if (auto clangModuleUnit =
536+
dyn_cast<ClangModuleUnit>(M->getFiles().front())) {
537+
auto exportedModuleName =
538+
M->getASTContext().getIdentifier(
539+
clangModuleUnit->getExportedModuleName());
540+
return addDeclBaseNameRef(exportedModuleName);
542541
}
542+
543543
assert(!M->getName().empty());
544544
return addDeclBaseNameRef(M->getName());
545545
}

test/ClangImporter/Inputs/privateframeworks/overlay/SomeKit.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ extension NSObject {
1515
public func doSomethingElse(_: SKWidget) { }
1616
}
1717

18-
extension SKWidgetError {
19-
public func getCode(from widget: SKWidget) -> SKWidgetError.Code {
18+
extension SKWidget.Error {
19+
public func getCode(from widget: SKWidget) -> SKWidget.Error.Code {
2020
return widget.getCurrentError()
2121
}
2222
}
2323

24-
extension SKWidgetError.Code {
24+
extension SKWidget.Error.Code {
2525
public var isBoom: Bool {
2626
return self == .boom
2727
}
@@ -42,7 +42,7 @@ public func inlineWidgetOperations(_ widget: SKWidget) {
4242
widget.doSomethingElse(widget)
4343
let obj = widget.anObject
4444
widget.anObject = obj
45-
_ = SKWidgetError(.boom).getCode(from: widget).isBoom
45+
_ = SKWidget.Error(.boom).getCode(from: widget).isBoom
4646
var hao: HasAnObject = widget
4747
someKitGlobalFunc()
4848
hao.anObject = widget

test/ClangImporter/Inputs/privateframeworks/withoutprivate/SomeKit.framework/Headers/SKWidget.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
@end
1515

1616
extern NSString * _Nonnull const SKWidgetErrorDomain;
17-
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) SKWidgetErrorCode : NSInteger {
17+
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) __attribute__((swift_name("SKWidget.Error"))) SKWidgetErrorCode : NSInteger {
1818
SKWidgetErrorNone = 0,
1919
SKWidgetErrorBoom = 1
2020
} SKWidgetErrorCode;

test/ClangImporter/Inputs/privateframeworks/withprivate/SomeKitCore.framework/Headers/SKWidget.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
@end
1616

1717
extern NSString * _Nonnull const SKWidgetErrorDomain;
18-
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) SKWidgetErrorCode : NSInteger {
18+
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) __attribute__((swift_name("SKWidget.Error"))) SKWidgetErrorCode : NSInteger {
1919
SKWidgetErrorNone = 0,
2020
SKWidgetErrorBoom = 1
2121
} SKWidgetErrorCode;

test/ClangImporter/private_frameworks.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func testWidget(widget: SKWidget) {
4040
}
4141

4242
func testError(widget: SKWidget) {
43-
let c: SKWidgetError.Code = SKWidgetError(.boom).getCode(from: widget)
43+
let c: SKWidget.Error.Code = SKWidget.Error(.boom).getCode(from: widget)
4444
if c.isBoom { }
4545
}
4646

0 commit comments

Comments
 (0)