Skip to content

[Serialization] Handle re-export of error enums harder #21880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1140,21 +1140,20 @@ 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) {
static bool isReExportedToModule(const ValueDecl *value,
const ModuleDecl *expectedModule) {
const DeclContext *valueDC = value->getDeclContext();
auto fromClangModule
= dyn_cast<ClangModuleUnit>(fromModule->getFiles().front());
= dyn_cast<ClangModuleUnit>(valueDC->getModuleScopeContext());
if (!fromClangModule)
return false;
std::string exportedName = fromClangModule->getExportedModuleName();

auto toClangModule
= dyn_cast<ClangModuleUnit>(toModule->getFiles().front());
if (!toClangModule)
return false;

return fromClangModule->getExportedModuleName() ==
toClangModule->getExportedModuleName();
= dyn_cast<ClangModuleUnit>(expectedModule->getFiles().front());
if (toClangModule)
return exportedName == toClangModule->getExportedModuleName();
return exportedName == expectedModule->getName().str();
}

/// Remove values from \p values that don't match the expected type or module.
Expand Down Expand Up @@ -1197,7 +1196,7 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
// module to the original definition in a base module.
if (expectedModule && !value->hasClangNode() &&
value->getModuleContext() != expectedModule &&
!reExportedToSameModule(value->getModuleContext(), expectedModule))
!isReExportedToModule(value, expectedModule))
return true;

// If we're expecting a member within a constrained extension with a
Expand Down Expand Up @@ -1357,6 +1356,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
if (entry.Kind != llvm::BitstreamEntry::Record)
return Identifier();

scratch.clear();
unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch,
&blobData);
switch (recordID) {
Expand Down
18 changes: 16 additions & 2 deletions test/ClangImporter/private_frameworks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withprivate -swift-version 4 %s -import-objc-header %S/Inputs/privateframeworks/bridging-somekitcore.h -verify

// Use the overlay without private frameworks.
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withoutprivate -I %t -swift-version 4 -import-objc-header %S/Inputs/privateframeworks/bridging-somekit.h %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withoutprivate -swift-version 4 -import-objc-header %S/Inputs/privateframeworks/bridging-somekit.h %s

// Build the overlay with public frameworks.
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -F %S/Inputs/privateframeworks/withoutprivate -o %t %S/Inputs/privateframeworks/overlay/SomeKit.swift
Expand All @@ -21,7 +21,18 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withprivate -swift-version 4 %s -import-objc-header %S/Inputs/privateframeworks/bridging-somekitcore.h -verify

// Use the overlay without private frameworks.
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withoutprivate -I %t -swift-version 4 %s -import-objc-header %S/Inputs/privateframeworks/bridging-somekit.h
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withoutprivate -swift-version 4 %s -import-objc-header %S/Inputs/privateframeworks/bridging-somekit.h

// Use something that uses the overlay.
// RUN: echo 'import private_frameworks; testErrorConformance()' > %t/main.swift

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -o %t -F %S/Inputs/privateframeworks/withprivate -swift-version 4 %s -import-objc-header %S/Inputs/privateframeworks/bridging-somekitcore.h
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withprivate %t/main.swift -verify
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withoutprivate %t/main.swift -verify

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -o %t -F %S/Inputs/privateframeworks/withoutprivate -swift-version 4 %s -import-objc-header %S/Inputs/privateframeworks/bridging-somekit.h
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withprivate %t/main.swift -verify
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -o /dev/null -F %S/Inputs/privateframeworks/withoutprivate %t/main.swift -verify

// REQUIRES: objc_interop

Expand Down Expand Up @@ -50,3 +61,6 @@ func testGlobals() {
SomeKit.someKitOtherGlobalFunc()
someKitOtherGlobalFunc()
}

public struct ErrorsOnly<T: Error> {}
public func testErrorConformance(_ code: ErrorsOnly<SKWidget.Error>? = nil) {}