Skip to content

Commit 575ff30

Browse files
elshtshortli
authored andcommitted
Option to disable printing package-name in public or private interface.
Having package-name flag in non-package interfaces causes them to be built as if belonging to a package, which causes an issue for a loading client outside of the package as follows. For example, when building X that depends on A with the following dependency chain: X --> A --> B --(package-only)--> C 1. X itself is not in the same package as A, B, and C. 2. When dependency scanning X, and opening up B, because the scan target is in a different package domain, the scanner decides that B's package-only dependency on C is to be ignored. 3. When then finally building A itself, it will load its dependencies, but because the .private.swiftinterface of A still specifies -package-name, when it loads B, it will then examine its dependencies and deem that this package-only dependency on C is required. Because (2) and (3) disagree, we get an error now when building the private A textual interface. rdar://130701866
1 parent 82dd1b9 commit 575ff30

File tree

6 files changed

+106
-1
lines changed

6 files changed

+106
-1
lines changed

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ struct ModuleInterfaceOptions {
6262
/// Print imports that are missing from the source and used in API.
6363
bool PrintMissingImports = true;
6464

65+
/// If true, package-name flag is not printed in either public or private
66+
/// interface file.
67+
bool DisablePackageNameForNonPackageInterface = false;
68+
6569
/// Intentionally print invalid syntax into the file.
6670
bool DebugPrintInvalidSyntax = false;
6771

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,11 @@ def disable_bridging_pch : Flag<["-"], "disable-bridging-pch">,
717717
Flags<[HelpHidden]>,
718718
HelpText<"Disable automatic generation of bridging PCH files">;
719719

720+
def disable_print_package_name_for_non_package_interface :
721+
Flag<["-"], "disable-print-package-name-for-non-package-interface">,
722+
Flags<[FrontendOption, NoDriverOption, ModuleInterfaceOption, HelpHidden]>,
723+
HelpText<"Disable adding package name to public or private interface">;
724+
720725
def lto : Joined<["-"], "lto=">,
721726
Flags<[FrontendOption, NoInteractiveOption]>,
722727
HelpText<"Specify the LTO type to either 'llvm-thin' or 'llvm-full'">;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
419419
Args.hasArg(OPT_debug_emit_invalid_swiftinterface_syntax);
420420
Opts.PrintMissingImports =
421421
!Args.hasArg(OPT_disable_print_missing_imports_in_module_interface);
422+
Opts.DisablePackageNameForNonPackageInterface |= Args.hasArg(OPT_disable_print_package_name_for_non_package_interface);
422423

423424
if (const Arg *A = Args.getLastArg(OPT_library_level)) {
424425
StringRef contents = A->getValue();

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,35 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
5959
<< InterfaceFormatVersion << "\n";
6060
out << "// " SWIFT_COMPILER_VERSION_KEY ": "
6161
<< ToolsVersion << "\n";
62+
63+
// Check if printing package-name is disabled for
64+
// non-package interfaces (by default, it's printed
65+
// in all interfaces).
66+
std::string flagsStr = Opts.Flags;
67+
if (Opts.DisablePackageNameForNonPackageInterface &&
68+
!Opts.printPackageInterface()) {
69+
size_t pkgIdx = 0;
70+
size_t end = flagsStr.size();
71+
auto pkgFlag = StringRef("-package-name ");
72+
size_t pkgLen = pkgFlag.size();
73+
74+
// Find the package-name flag and its value and
75+
// drop them. There can be multiple package-name
76+
// flags passed, so drop them all.
77+
while (pkgIdx < end) {
78+
// First, find "-package-name "
79+
pkgIdx = flagsStr.find(pkgFlag, 0);
80+
if (pkgIdx == std::string::npos)
81+
break;
82+
// If found, find the next flag's starting pos.
83+
auto next = flagsStr.find_first_of("-", pkgIdx + pkgLen + 1);
84+
// Remove the substr in-place.
85+
flagsStr.erase(pkgIdx, next - pkgIdx);
86+
}
87+
}
88+
6289
out << "// " SWIFT_MODULE_FLAGS_KEY ": "
63-
<< Opts.Flags;
90+
<< flagsStr;
6491

6592
// Insert additional -module-alias flags
6693
if (Opts.AliasModuleNames) {

lib/Sema/TypeCheckAttr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,12 @@ bool AttributeChecker::visitAbstractAccessControlAttr(
10581058
D->getASTContext().LangOpts.PackageName.empty() &&
10591059
File && File->Kind != SourceFileKind::Interface) {
10601060
// `package` modifier used outside of a package.
1061+
// Error if a source file contains a package decl or `package import` but
1062+
// no package-name is passed.
1063+
// Note that if the file containing the package decl is a public (or private)
1064+
// interface file, the decl must be @usableFromInline (or "inlinable"),
1065+
// effectively getting "public" visibility; in such case, package-name is
1066+
// not needed, and typecheck on those decls are skipped.
10611067
diagnose(attr->getLocation(), diag::access_control_requires_package_name,
10621068
isa<ValueDecl>(D), D);
10631069
return true;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %empty-directory(%t)
2+
3+
/// Do not print package-name for public or private interfaces
4+
// RUN: %target-build-swift -emit-module %s -I %t \
5+
// RUN: -module-name Bar -package-name foopkg \
6+
// RUN: -enable-library-evolution -swift-version 6 \
7+
// RUN: -package-name barpkg \
8+
// RUN: -Xfrontend -disable-print-package-name-for-non-package-interface \
9+
// RUN: -emit-module-interface-path %t/Bar.swiftinterface \
10+
// RUN: -emit-private-module-interface-path %t/Bar.private.swiftinterface \
11+
// RUN: -emit-package-module-interface-path %t/Bar.package.swiftinterface
12+
13+
// RUN: %FileCheck %s --check-prefix=CHECK-PUBLIC < %t/Bar.swiftinterface
14+
// RUN: %FileCheck %s --check-prefix=CHECK-PRIVATE < %t/Bar.private.swiftinterface
15+
// RUN: %FileCheck %s --check-prefix=CHECK-PACKAGE < %t/Bar.package.swiftinterface
16+
17+
// CHECK-PUBLIC-NOT: -package-name foopkg
18+
// CHECK-PUBLIC-NOT: -package-name barpkg
19+
// CHECK-PRIVATE-NOT: -package-name foopkg
20+
// CHECK-PRIVATE-NOT: -package-name barpkg
21+
// CHECK-PACKAGE-NOT: -package-name foopkg
22+
// CHECK-PACKAGE: -package-name barpkg
23+
24+
// CHECK-PUBLIC: -module-name Bar
25+
// CHECK-PRIVATE: -module-name Bar
26+
// CHECK-PACKAGE: -module-name Bar
27+
28+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Bar.swiftinterface -o %t/Bar.swiftmodule -module-name Bar
29+
// RUN: rm -rf %t/Bar.swiftmodule
30+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Bar.private.swiftinterface -o %t/Bar.swiftmodule -module-name Bar
31+
// RUN: rm -rf %t/Bar.swiftmodule
32+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Bar.package.swiftinterface -o %t/Bar.swiftmodule -module-name Bar
33+
34+
// RUN: rm -rf %t/Bar.swiftmodule
35+
// RUN: rm -rf %t/Bar.swiftinterface
36+
// RUN: rm -rf %t/Bar.private.swiftinterface
37+
// RUN: rm -rf %t/Bar.package.swiftinterface
38+
39+
/// By default, -package-name is printed in all interfaces.
40+
// RUN: %target-build-swift -emit-module %s -I %t \
41+
// RUN: -module-name Bar -package-name barpkg \
42+
// RUN: -enable-library-evolution -swift-version 6 \
43+
// RUN: -emit-module-interface-path %t/Bar.swiftinterface \
44+
// RUN: -emit-private-module-interface-path %t/Bar.private.swiftinterface \
45+
// RUN: -emit-package-module-interface-path %t/Bar.package.swiftinterface
46+
47+
// RUN: %FileCheck %s < %t/Bar.swiftinterface
48+
// RUN: %FileCheck %s < %t/Bar.private.swiftinterface
49+
// RUN: %FileCheck %s < %t/Bar.package.swiftinterface
50+
51+
// CHECK: -package-name barpkg
52+
// CHECK: -module-name Bar
53+
54+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Bar.swiftinterface -o %t/Bar.swiftmodule -module-name Bar
55+
// RUN: rm -rf %t/Bar.swiftmodule
56+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Bar.private.swiftinterface -o %t/Bar.swiftmodule -module-name Bar
57+
// RUN: rm -rf %t/Bar.swiftmodule
58+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Bar.package.swiftinterface -o %t/Bar.swiftmodule -module-name Bar
59+
60+
public struct PubStruct {}
61+
@_spi(bar) public struct SPIStruct {}
62+
package struct PkgStruct {}

0 commit comments

Comments
 (0)