mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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.
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "swift/AST/PrettyStackTrace.h"
|
||||
#include "swift/AST/ProtocolConformance.h"
|
||||
#include "swift/ClangImporter/ClangImporter.h"
|
||||
#include "swift/ClangImporter/ClangModule.h"
|
||||
#include "swift/Serialization/BCReadingExtras.h"
|
||||
#include "swift/Serialization/SerializedModuleLoader.h"
|
||||
#include "swift/Basic/Defer.h"
|
||||
@@ -1098,6 +1099,23 @@ getActualCtorInitializerKind(uint8_t raw) {
|
||||
return None;
|
||||
}
|
||||
|
||||
/// Determine whether the two modules are re-exported to the same module.
|
||||
static bool reExportedToSameModule(const ModuleDecl *fromModule,
|
||||
const ModuleDecl *toModule) {
|
||||
auto fromClangModule
|
||||
= dyn_cast<ClangModuleUnit>(fromModule->getFiles().front());
|
||||
if (!fromClangModule)
|
||||
return false;
|
||||
|
||||
auto toClangModule
|
||||
= dyn_cast<ClangModuleUnit>(toModule->getFiles().front());
|
||||
if (!toClangModule)
|
||||
return false;
|
||||
|
||||
return fromClangModule->getExportedModuleName() ==
|
||||
toClangModule->getExportedModuleName();
|
||||
}
|
||||
|
||||
/// Remove values from \p values that don't match the expected type or module.
|
||||
///
|
||||
/// Any of \p expectedTy, \p expectedModule, or \p expectedGenericSig can be
|
||||
@@ -1130,7 +1148,8 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
|
||||
// FIXME: Should be able to move a value from an extension in a derived
|
||||
// module to the original definition in a base module.
|
||||
if (expectedModule && !value->hasClangNode() &&
|
||||
value->getModuleContext() != expectedModule)
|
||||
value->getModuleContext() != expectedModule &&
|
||||
!reExportedToSameModule(value->getModuleContext(), expectedModule))
|
||||
return true;
|
||||
|
||||
// If we're expecting a member within a constrained extension with a
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "swift/ClangImporter/ClangModule.h"
|
||||
#include "swift/Serialization/SerializationOptions.h"
|
||||
|
||||
#include "clang/Basic/Module.h"
|
||||
// FIXME: We're just using CompilerInstance::createOutputFile.
|
||||
// This API should be sunk down to LLVM.
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
@@ -533,13 +532,14 @@ IdentifierID Serializer::addModuleRef(const ModuleDecl *M) {
|
||||
|
||||
// If we're referring to a member of a private module that will be
|
||||
// re-exported via a public module, record the public module's name.
|
||||
if (auto clangModule = M->findUnderlyingClangModule()) {
|
||||
if (!clangModule->ExportAsModule.empty()) {
|
||||
auto publicModuleName =
|
||||
M->getASTContext().getIdentifier(clangModule->ExportAsModule);
|
||||
return addDeclBaseNameRef(publicModuleName);
|
||||
}
|
||||
if (auto clangModuleUnit =
|
||||
dyn_cast<ClangModuleUnit>(M->getFiles().front())) {
|
||||
auto exportedModuleName =
|
||||
M->getASTContext().getIdentifier(
|
||||
clangModuleUnit->getExportedModuleName());
|
||||
return addDeclBaseNameRef(exportedModuleName);
|
||||
}
|
||||
|
||||
assert(!M->getName().empty());
|
||||
return addDeclBaseNameRef(M->getName());
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ extension NSObject {
|
||||
public func doSomethingElse(_: SKWidget) { }
|
||||
}
|
||||
|
||||
extension SKWidgetError {
|
||||
public func getCode(from widget: SKWidget) -> SKWidgetError.Code {
|
||||
extension SKWidget.Error {
|
||||
public func getCode(from widget: SKWidget) -> SKWidget.Error.Code {
|
||||
return widget.getCurrentError()
|
||||
}
|
||||
}
|
||||
|
||||
extension SKWidgetError.Code {
|
||||
extension SKWidget.Error.Code {
|
||||
public var isBoom: Bool {
|
||||
return self == .boom
|
||||
}
|
||||
@@ -42,7 +42,7 @@ public func inlineWidgetOperations(_ widget: SKWidget) {
|
||||
widget.doSomethingElse(widget)
|
||||
let obj = widget.anObject
|
||||
widget.anObject = obj
|
||||
_ = SKWidgetError(.boom).getCode(from: widget).isBoom
|
||||
_ = SKWidget.Error(.boom).getCode(from: widget).isBoom
|
||||
var hao: HasAnObject = widget
|
||||
someKitGlobalFunc()
|
||||
hao.anObject = widget
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
@end
|
||||
|
||||
extern NSString * _Nonnull const SKWidgetErrorDomain;
|
||||
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) SKWidgetErrorCode : NSInteger {
|
||||
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) __attribute__((swift_name("SKWidget.Error"))) SKWidgetErrorCode : NSInteger {
|
||||
SKWidgetErrorNone = 0,
|
||||
SKWidgetErrorBoom = 1
|
||||
} SKWidgetErrorCode;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
@end
|
||||
|
||||
extern NSString * _Nonnull const SKWidgetErrorDomain;
|
||||
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) SKWidgetErrorCode : NSInteger {
|
||||
typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) __attribute__((swift_name("SKWidget.Error"))) SKWidgetErrorCode : NSInteger {
|
||||
SKWidgetErrorNone = 0,
|
||||
SKWidgetErrorBoom = 1
|
||||
} SKWidgetErrorCode;
|
||||
|
||||
@@ -40,7 +40,7 @@ func testWidget(widget: SKWidget) {
|
||||
}
|
||||
|
||||
func testError(widget: SKWidget) {
|
||||
let c: SKWidgetError.Code = SKWidgetError(.boom).getCode(from: widget)
|
||||
let c: SKWidget.Error.Code = SKWidget.Error(.boom).getCode(from: widget)
|
||||
if c.isBoom { }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user