Skip to content

Commit b20107e

Browse files
committed
Sema: fix reporting reexporting submodules imports as unused in API
Importing a clang submodule from Swift implies importing the top-level module too. We make sure we don't warn on the import of the top-level module as being unused when the submodule is used by associating all references to the top-level module instead of submodules. This change applies the same logic for transitive imports, marking the import of the top-level module as used instead of the submodule with the `export *`. In the updated test, this silences the following warning: ``` public import of 'ClangReexportedSubmodulePublic' was not used in public declarations or inlinable code ``` rdar://139492772
1 parent a9d5903 commit b20107e

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

lib/Sema/TypeCheckAccess.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,8 +2517,11 @@ void swift::recordRequiredImportAccessLevelForDecl(
25172517
if (auto attributedImport = sf->getImportAccessLevel(definingModule)) {
25182518
auto importedModule = attributedImport->module.importedModule;
25192519

2520-
// If the defining module is transitively imported, mark the responsible
2521-
// module as requiring the minimum access level too.
2520+
// Ignore submodules, same behavior from `getModuleContext` above.
2521+
importedModule = importedModule->getTopLevelModule();
2522+
2523+
// If the defining module is transitively imported, mark the locally
2524+
// imported module as requiring the minimum access level too.
25222525
if (importedModule != definingModule)
25232526
sf->registerRequiredAccessLevelForModule(importedModule, accessLevel);
25242527

test/Sema/superfluously-public-imports.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
// RUN: %target-swift-frontend -typecheck %t/ClientOfClangModules.swift -I %t \
3333
// RUN: -package-name pkg -Rmodule-api-import \
3434
// RUN: -enable-upcoming-feature InternalImportsByDefault -verify
35+
// RUN: %target-swift-frontend -typecheck %t/ClientOfClangReexportedSubmodules.swift -I %t \
36+
// RUN: -package-name pkg -Rmodule-api-import \
37+
// RUN: -enable-upcoming-feature InternalImportsByDefault -verify
3538
// RUN: %target-swift-frontend -typecheck %t/Client_Swift5.swift -I %t \
3639
// RUN: -swift-version 5 -verify
3740

@@ -283,6 +286,21 @@ module ClangTopModule {
283286
}
284287
}
285288

289+
module ClangReexportedSubmodulePublic {
290+
header "ClangReexportedSubmodulePublic.h"
291+
module ClangReexportedSubmodulePublicSub {
292+
header "ClangReexportedSubmodulePublicSub.h"
293+
export *
294+
}
295+
}
296+
297+
module ClangReexportedSubmoduleTop {
298+
header "ClangReexportedSubmoduleTop.h"
299+
module ClangReexportedSubmoduleSub {
300+
header "ClangReexportedSubmoduleSub.h"
301+
}
302+
}
303+
286304
//--- ClangSimpleUnused.h
287305
//--- ClangSimple.h
288306
struct ClangSimpleType {};
@@ -298,6 +316,15 @@ struct ClangSubmoduleSubmoduleType {};
298316
struct ClangTopModuleType {};
299317
//--- ClangTopModuleSubmodule.h
300318

319+
//--- ClangReexportedSubmodulePublic.h
320+
//--- ClangReexportedSubmodulePublicSub.h
321+
#import <ClangReexportedSubmoduleSub.h>
322+
323+
//--- ClangReexportedSubmoduleTop.h
324+
//--- ClangReexportedSubmoduleSub.h
325+
typedef struct _TypedefTypeUnderlying {
326+
} TypedefType;
327+
301328
//--- ClientOfClangModules.swift
302329
public import ClangSimple
303330
public import ClangSimpleUnused // expected-warning {{public import of 'ClangSimpleUnused' was not used in public declarations or inlinable code}}
@@ -310,3 +337,9 @@ public import ClangTopModule.ClangTopModuleSubmodule
310337
public func clangUser(a: ClangSimpleType) {} // expected-remark {{struct 'ClangSimpleType' is imported via 'ClangSimple'}}
311338
public func clangUser(a: ClangSubmoduleSubmoduleType) {} // expected-remark {{struct 'ClangSubmoduleSubmoduleType' is imported via 'ClangSubmodule'}}
312339
public func clangUser(a: ClangTopModuleType) {} // expected-remark {{struct 'ClangTopModuleType' is imported via 'ClangTopModule'}}
340+
341+
//--- ClientOfClangReexportedSubmodules.swift
342+
public import ClangReexportedSubmodulePublic.ClangReexportedSubmodulePublicSub
343+
344+
public func useTypedefed(a: TypedefType) {} // expected-remark 2 {{typealias underlying type struct '_TypedefTypeUnderlying' is imported via 'ClangReexportedSubmodulePublicSub', which reexports definition from 'ClangReexportedSubmoduleTop'}}
345+
// expected-remark @-1 {{type alias 'TypedefType' is imported via 'ClangReexportedSubmodulePublicSub', which reexports definition from 'ClangReexportedSubmoduleTop'}}

0 commit comments

Comments
 (0)