Skip to content

Commit ab38752

Browse files
committed
[ModuleInterface] Ignore export_as in private swiftinterface
Introduce a new behavior when printing references to modules with an `export_as` definition. Use the `export_as` name in the public swiftinterface and the real module name in the private swiftinterface. This has some limits but should still be an improvement over the current behavior. First, the we use the `export_as` names only for references to clang decls, not Swift decls with an underlying module defining an `export_as`. Second, we always print the `export_as` name in the public swiftinterface, even in the original swiftinterface file when the `export_as` target is likely not know, so that generated swiftinterface is still broken. This behavior is enabled by the flags `-enable-experimental-feature ModuleInterfaceExportAs` or the `SWIFT_DEBUG_USE_EXPORTED_MODULE_NAME_IN_PUBLIC_ONLY` env var. We may consider turning it on by default in the future. rdar://98532918
1 parent 010973c commit ab38752

File tree

5 files changed

+132
-1
lines changed

5 files changed

+132
-1
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ struct PrintOptions {
649649
bool preferTypeRepr,
650650
bool printFullConvention,
651651
bool printSPIs,
652+
bool useExportedModuleNames,
652653
bool aliasModuleNames,
653654
llvm::SmallSet<StringRef, 4>
654655
*aliasModuleNamesTargets

include/swift/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ EXPERIMENTAL_FEATURE(OneWayClosureParameters, false)
105105
EXPERIMENTAL_FEATURE(TypeWitnessSystemInference, false)
106106
EXPERIMENTAL_FEATURE(ResultBuilderASTTransform, true)
107107
EXPERIMENTAL_FEATURE(LayoutPrespecialization, false)
108+
EXPERIMENTAL_FEATURE(ModuleInterfaceExportAs, true)
108109

109110
/// Whether to enable experimental differentiable programming features:
110111
/// `@differentiable` declaration attribute, etc.

lib/AST/ASTPrinter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
132132
bool preferTypeRepr,
133133
bool printFullConvention,
134134
bool printSPIs,
135+
bool useExportedModuleNames,
135136
bool aliasModuleNames,
136137
llvm::SmallSet<StringRef, 4>
137138
*aliasModuleNamesTargets
@@ -145,7 +146,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
145146
result.FullyQualifiedTypes = true;
146147
result.FullyQualifiedTypesIfAmbiguous = true;
147148
result.FullyQualifiedExtendedTypesIfAmbiguous = true;
148-
result.UseExportedModuleNames = true;
149+
result.UseExportedModuleNames = useExportedModuleNames;
149150
result.AllowNullTypes = false;
150151
result.SkipImports = true;
151152
result.OmitNameOfInaccessibleProperties = true;
@@ -3070,6 +3071,10 @@ static bool usesFeatureLayoutPrespecialization(Decl *decl) {
30703071
return false;
30713072
}
30723073

3074+
static bool usesFeatureModuleInterfaceExportAs(Decl *decl) {
3075+
return false;
3076+
}
3077+
30733078
static bool usesFeatureNamedOpaqueTypes(Decl *decl) {
30743079
return false;
30753080
}

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,9 +788,18 @@ bool swift::emitSwiftInterface(raw_ostream &out,
788788

789789
printImports(out, Opts, M);
790790

791+
static bool forceUseExportedModuleNameInPublicOnly =
792+
getenv("SWIFT_DEBUG_USE_EXPORTED_MODULE_NAME_IN_PUBLIC_ONLY");
793+
bool useExportedModuleNameInPublicOnly =
794+
M->getASTContext().LangOpts.hasFeature(Feature::ModuleInterfaceExportAs) ||
795+
forceUseExportedModuleNameInPublicOnly;
796+
bool useExportedModuleNames = !(useExportedModuleNameInPublicOnly &&
797+
Opts.PrintPrivateInterfaceContent);
798+
791799
const PrintOptions printOptions = PrintOptions::printSwiftInterfaceFile(
792800
M, Opts.PreserveTypesAsWritten, Opts.PrintFullConvention,
793801
Opts.PrintPrivateInterfaceContent,
802+
useExportedModuleNames,
794803
Opts.AliasModuleNames, &aliasModuleNamesTargets);
795804
InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;
796805

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/// Test the logic printing the export_as name in public swiftinterfaces
2+
/// and the real source module name in the private swiftinterfaces.
3+
4+
// RUN: %empty-directory(%t)
5+
// RUN: split-file %s %t
6+
7+
/// Build lib with an export_as.
8+
// RUN: %target-swift-frontend -emit-module %t/Exported.swift \
9+
// RUN: -module-name Exported -swift-version 5 -I %t \
10+
// RUN: -enable-library-evolution \
11+
// RUN: -emit-module-path %t/Exported.swiftmodule \
12+
// RUN: -emit-module-interface-path %t/Exported.swiftinterface \
13+
// RUN: -emit-private-module-interface-path %t/Exported.private.swiftinterface \
14+
// RUN: -enable-experimental-feature ModuleInterfaceExportAs
15+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exported.private.swiftinterface) -module-name Exported -I %t
16+
// RUN: cat %t/Exported.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTER %s
17+
// RUN: cat %t/Exported.private.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTED %s
18+
19+
/// The public swiftinterface only builds under the name of Exporter.
20+
// RUN: sed -e "s/module-name Exported/module-name Exporter/" -ibk %t/Exported.swiftinterface
21+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exported.swiftinterface) -I %t -module-name Exporter
22+
23+
/// Build lib with an @exported import of the exported one.
24+
/// Default/old behavior.
25+
// RUN: %target-swift-frontend -emit-module %t/Exporter.swift \
26+
// RUN: -module-name Exporter -swift-version 5 -I %t \
27+
// RUN: -enable-library-evolution \
28+
// RUN: -emit-module-path %t/Exporter.swiftmodule \
29+
// RUN: -emit-module-interface-path %t/Exporter.swiftinterface \
30+
// RUN: -emit-private-module-interface-path %t/Exporter.private.swiftinterface
31+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exporter.swiftinterface) -I %t
32+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exporter.private.swiftinterface) -module-name Exporter -I %t
33+
// RUN: cat %t/Exporter.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTER %s
34+
// RUN: cat %t/Exporter.private.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTER %s
35+
36+
/// Build lib with an @exported import of the exported one.
37+
/// New behavior via flag.
38+
// RUN: %target-swift-frontend -emit-module %t/Exporter.swift \
39+
// RUN: -module-name Exporter -swift-version 5 -I %t \
40+
// RUN: -enable-library-evolution \
41+
// RUN: -emit-module-path %t/Exporter.swiftmodule \
42+
// RUN: -emit-module-interface-path %t/Exporter.swiftinterface \
43+
// RUN: -emit-private-module-interface-path %t/Exporter.private.swiftinterface \
44+
// RUN: -enable-experimental-feature ModuleInterfaceExportAs
45+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exporter.swiftinterface) -I %t
46+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exporter.private.swiftinterface) -module-name Exporter -I %t
47+
// RUN: cat %t/Exporter.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTER %s
48+
// RUN: cat %t/Exporter.private.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTED %s
49+
50+
/// Build lib with an @exported import of the exported one.
51+
/// New behavior via env var.
52+
// RUN: env SWIFT_DEBUG_USE_EXPORTED_MODULE_NAME_IN_PUBLIC_ONLY=1 \
53+
// RUN: %target-swift-frontend -emit-module %t/Exporter.swift \
54+
// RUN: -module-name Exporter -swift-version 5 -I %t \
55+
// RUN: -enable-library-evolution \
56+
// RUN: -emit-module-path %t/Exporter.swiftmodule \
57+
// RUN: -emit-module-interface-path %t/Exporter.swiftinterface \
58+
// RUN: -emit-private-module-interface-path %t/Exporter.private.swiftinterface
59+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exporter.swiftinterface) -I %t
60+
// RUN: %target-swift-typecheck-module-from-interface(%t/Exporter.private.swiftinterface) -module-name Exporter -I %t
61+
// RUN: cat %t/Exporter.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTER %s
62+
// RUN: cat %t/Exporter.private.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTED %s
63+
64+
/// Build a client of the exporter lib.
65+
// RUN: %target-swift-frontend -emit-module %t/Client.swift \
66+
// RUN: -module-name Client -swift-version 5 -I %t \
67+
// RUN: -enable-library-evolution \
68+
// RUN: -emit-module-path %t/Client.swiftmodule \
69+
// RUN: -emit-module-interface-path %t/Client.swiftinterface \
70+
// RUN: -emit-private-module-interface-path %t/Client.private.swiftinterface \
71+
// RUN: -enable-experimental-feature ModuleInterfaceExportAs
72+
// RUN: %target-swift-typecheck-module-from-interface(%t/Client.swiftinterface) -I %t
73+
// RUN: %target-swift-typecheck-module-from-interface(%t/Client.private.swiftinterface) -module-name Client -I %t
74+
// RUN: cat %t/Client.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTER %s
75+
// RUN: cat %t/Client.private.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTED %s
76+
77+
/// Build a client of the exporter lib.
78+
// RUN: rm %t/Exporter.private.swiftinterface %t/Exporter.swiftmodule
79+
// RUN: %target-swift-frontend -emit-module %t/Client.swift \
80+
// RUN: -module-name Client -swift-version 5 -I %t \
81+
// RUN: -enable-library-evolution \
82+
// RUN: -emit-module-path %t/Client.swiftmodule \
83+
// RUN: -emit-module-interface-path %t/Client.swiftinterface \
84+
// RUN: -emit-private-module-interface-path %t/Client.private.swiftinterface \
85+
// RUN: -enable-experimental-feature ModuleInterfaceExportAs
86+
// RUN: %target-swift-typecheck-module-from-interface(%t/Client.swiftinterface) -I %t
87+
// RUN: %target-swift-typecheck-module-from-interface(%t/Client.private.swiftinterface) -module-name Client -I %t
88+
// RUN: cat %t/Client.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTER %s
89+
// RUN: cat %t/Client.private.swiftinterface | %FileCheck -check-prefix=CHECK-USE-EXPORTED %s
90+
91+
//--- module.modulemap
92+
module Exported {
93+
export_as Exporter
94+
header "Exported.h"
95+
}
96+
97+
//--- Exported.h
98+
struct exportedClangType {};
99+
100+
//--- Exported.swift
101+
@_exported import Exported
102+
103+
public func foo(a: exportedClangType) {}
104+
// CHECK-USE-EXPORTED: Exported.exportedClangType
105+
// CHECK-USE-EXPORTER: Exporter.exportedClangType
106+
107+
//--- Exporter.swift
108+
@_exported import Exported
109+
110+
public func foo(a: exportedClangType) {}
111+
112+
//--- Client.swift
113+
import Exporter
114+
115+
public func foo(a: exportedClangType) {}

0 commit comments

Comments
 (0)