Skip to content

Commit 0a71a5c

Browse files
committed
[Sema] Report conflicts between @_exported and non-public imports
@_exported can only be used on public imports, it's incompatible with any other access level. This implementation doesn't take into account Swift 6 mode.
1 parent adda34b commit 0a71a5c

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,9 @@ ERROR(access_level_on_import_unsupported, none,
20572057
"only 'public', 'package', 'internal', 'fileprivate' and 'private' "
20582058
"are unsupported",
20592059
(DeclAttribute))
2060+
ERROR(access_level_conflict_with_exported,none,
2061+
"'%0' is incompatible with %1; it can only be applied to public imports",
2062+
(DeclAttribute, DeclAttribute))
20602063

20612064
// Opaque return types
20622065
ERROR(opaque_type_invalid_constraint,none,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,14 @@ bool AttributeChecker::visitAbstractAccessControlAttr(
970970
attr);
971971
return true;
972972
}
973+
974+
if (attr->getAccess() != AccessLevel::Public) {
975+
if (auto exportedAttr = D->getAttrs().getAttribute<ExportedAttr>()) {
976+
diagnoseAndRemoveAttr(attr, diag::access_level_conflict_with_exported,
977+
exportedAttr, attr);
978+
return true;
979+
}
980+
}
973981
}
974982

975983
return false;

test/Sema/conflicting-import-restrictions.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,35 @@
3535

3636
//--- SPIOnly_IOI_Exported.swift
3737
@_spiOnly @_implementationOnly @_exported import Lib // expected-error {{module 'Lib' cannot be both exported and implementation-only}}
38+
39+
/// Access levels on imports
40+
// RUN: %target-swift-frontend -typecheck %t/Public_Exported.swift -I %t -verify \
41+
// RUN: -experimental-spi-only-imports -verify \
42+
// RUN: -enable-experimental-feature AccessLevelOnImport
43+
// RUN: %target-swift-frontend -typecheck %t/Package_Exported.swift -I %t -verify \
44+
// RUN: -experimental-spi-only-imports -verify \
45+
// RUN: -enable-experimental-feature AccessLevelOnImport
46+
// RUN: %target-swift-frontend -typecheck %t/Internal_Exported.swift -I %t -verify \
47+
// RUN: -experimental-spi-only-imports -verify \
48+
// RUN: -enable-experimental-feature AccessLevelOnImport
49+
// RUN: %target-swift-frontend -typecheck %t/Fileprivate_Exported.swift -I %t -verify \
50+
// RUN: -experimental-spi-only-imports -verify \
51+
// RUN: -enable-experimental-feature AccessLevelOnImport
52+
// RUN: %target-swift-frontend -typecheck %t/Private_Exported.swift -I %t -verify \
53+
// RUN: -experimental-spi-only-imports -verify \
54+
// RUN: -enable-experimental-feature AccessLevelOnImport
55+
56+
//--- Public_Exported.swift
57+
@_exported public import Lib
58+
59+
//--- Package_Exported.swift
60+
@_exported package import Lib // expected-error {{'@_exported' is incompatible with 'package'; it can only be applied to public imports}}
61+
62+
//--- Internal_Exported.swift
63+
@_exported internal import Lib // expected-error {{'@_exported' is incompatible with 'internal'; it can only be applied to public imports}}
64+
65+
//--- Fileprivate_Exported.swift
66+
@_exported fileprivate import Lib // expected-error {{'@_exported' is incompatible with 'fileprivate'; it can only be applied to public imports}}
67+
68+
//--- Private_Exported.swift
69+
@_exported private import Lib // expected-error {{'@_exported' is incompatible with 'private'; it can only be applied to public imports}}

0 commit comments

Comments
 (0)