Skip to content

Commit d73f721

Browse files
committed
Opt in to generate internal contents in module and allow non-resilient access by clients
1 parent e7e5f53 commit d73f721

18 files changed

+85
-40
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,9 +752,8 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
752752
/// Whether this module has been built with C++ interoperability enabled.
753753
HasCxxInteroperability : 1,
754754

755-
/// Whether this module has been built with -experimental-skip-non-exportable-decls
756-
/// or -experimental-skip-non-inlinable-function-bodies.
757-
OnlyHasExportableDecls : 1
755+
/// Whether this module has been built with -experimental-allow-non-resilient-access.
756+
AllowNonResilientAccess : 1
758757
);
759758

760759
SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ WARNING(emit_reference_dependencies_without_primary_file,none,
168168

169169
WARNING(ignoring_option_requires_option,none,
170170
"ignoring %0 (requires %1)", (StringRef, StringRef))
171+
WARNING(warn_ignore_option_due_to_conflict,none,
172+
"ignoring %0 (conflicts with %1)", (StringRef, StringRef))
171173

172174
WARNING(warn_implicit_concurrency_import_failed,none,
173175
"unable to perform implicit import of \"_Concurrency\" module: no such module found", ())

include/swift/AST/Module.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -711,13 +711,12 @@ class ModuleDecl
711711
Bits.ModuleDecl.IsBuiltFromInterface = flag;
712712
}
713713

714-
/// Returns true if the module was built with -experimental-skip-non-exportable-decls
715-
/// or -experimental-skip-non-inlinable-function-bodies.
716-
bool onlyHasExportableDecls() const {
717-
return Bits.ModuleDecl.OnlyHasExportableDecls;
714+
/// Returns true if the module was built with -experimental-allow-non-resilient-access.
715+
bool allowNonResilientAccess() const {
716+
return Bits.ModuleDecl.AllowNonResilientAccess;
718717
}
719-
void setOnlyHasExportableDecls(bool flag = true) {
720-
Bits.ModuleDecl.OnlyHasExportableDecls = flag;
718+
void setAllowNonResilientAccess(bool flag = true) {
719+
Bits.ModuleDecl.AllowNonResilientAccess = flag;
721720
}
722721

723722
/// Returns true if this module is a non-Swift module that was imported into

include/swift/Frontend/FrontendOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,11 @@ class FrontendOptions {
311311
/// Should we skip decls that cannot be referenced externally?
312312
bool SkipNonExportableDecls = false;
313313

314+
/// True if -experimental-allow-non-resilient-access is passed and built from source
315+
/// without -enable-library-evolution. This overrides \c SkipNonExportableDecls
316+
/// (-experimental-skip-non-exportable-decls).
317+
bool AllowNonResilientAccess = false;
318+
314319
/// Should we warn if an imported module needed to be rebuilt from a
315320
/// module interface file?
316321
bool RemarkOnRebuildFromModuleInterface = false;

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,10 @@ def experimental_package_bypass_resilience : Flag<["-"], "experimental-package-b
524524
Flags<[FrontendOption]>,
525525
HelpText<"Enable optimization to bypass resilience within a package">;
526526

527+
def experimental_allow_non_resilient_access : Flag<["-"], "experimental-allow-non-resilient-access">,
528+
Flags<[FrontendOption]>,
529+
HelpText<"Allow non-resilient access by generating all contents besides exportable decls">;
530+
527531
def library_level : Separate<["-"], "library-level">,
528532
MetaVarName<"<level>">,
529533
Flags<[HelpHidden, FrontendOption, ModuleInterfaceOption]>,

include/swift/Serialization/Validation.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class ExtendedValidationInfo {
140140
unsigned IsAllowModuleWithCompilerErrorsEnabled : 1;
141141
unsigned IsConcurrencyChecked : 1;
142142
unsigned HasCxxInteroperability : 1;
143-
unsigned OnlyHasExportableDecls: 1;
143+
unsigned AllowNonResilientAccess: 1;
144144
} Bits;
145145
public:
146146
ExtendedValidationInfo() : Bits() {}
@@ -205,9 +205,9 @@ class ExtendedValidationInfo {
205205
void setIsBuiltFromInterface(bool val) {
206206
Bits.IsBuiltFromInterface = val;
207207
}
208-
bool onlyHasExportableDecls() const { return Bits.OnlyHasExportableDecls; }
209-
void setOnlyHasExportableDecls(bool val) {
210-
Bits.OnlyHasExportableDecls = val;
208+
bool allowNonResilientAccess() const { return Bits.AllowNonResilientAccess; }
209+
void setAllowNonResilientAccess(bool val) {
210+
Bits.AllowNonResilientAccess = val;
211211
}
212212
bool isAllowModuleWithCompilerErrorsEnabled() {
213213
return Bits.IsAllowModuleWithCompilerErrorsEnabled;

lib/AST/Decl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4217,8 +4217,7 @@ bool ValueDecl::bypassResilienceInPackage(ModuleDecl *accessingModule) const {
42174217
return getASTContext().LangOpts.EnableBypassResilienceInPackage &&
42184218
getModuleContext()->inSamePackage(accessingModule) &&
42194219
!getModuleContext()->isBuiltFromInterface() &&
4220-
!getModuleContext()->onlyHasExportableDecls() &&
4221-
!getModuleContext()->isTestingEnabled();
4220+
!getModuleContext()->allowNonResilientAccess();
42224221
}
42234222

42244223
/// Given the formal access level for using \p VD, compute the scope where

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
722722
Bits.ModuleDecl.IsConcurrencyChecked = 0;
723723
Bits.ModuleDecl.ObjCNameLookupCachePopulated = 0;
724724
Bits.ModuleDecl.HasCxxInteroperability = 0;
725+
Bits.ModuleDecl.AllowNonResilientAccess = 0;
725726
}
726727

727728
void ModuleDecl::setIsSystemModule(bool flag) {

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,22 @@ bool ArgsToFrontendOptionsConverter::convert(
295295
A->getOption().matches(OPT_serialize_debugging_options);
296296
}
297297

298+
// To allow non-resilient access from clients, internal contents
299+
// besides exportable decls should be generated. If built from
300+
// interface, or with -enable-library-evolution, we ignore this
301+
// option (-experimental-allow-non-resilient-access). This option
302+
// will however override -experimental-skip-non-exportable-decls
303+
// if both are passed.
304+
Opts.AllowNonResilientAccess = Args.hasArg(OPT_experimental_allow_non_resilient_access);
305+
298306
if (Args.hasArg(OPT_enable_library_evolution)) {
307+
if (Opts.AllowNonResilientAccess) {
308+
Diags.diagnose(SourceLoc(), diag::warn_ignore_option_due_to_conflict,
309+
"-experimental-allow-non-resilient-access",
310+
"-enable-library-evolution");
311+
Opts.AllowNonResilientAccess = false;
312+
}
313+
299314
Opts.SkipNonExportableDecls |=
300315
Args.hasArg(OPT_experimental_skip_non_exportable_decls);
301316

@@ -304,10 +319,26 @@ bool ArgsToFrontendOptionsConverter::convert(
304319
Args.hasArg(
305320
OPT_experimental_skip_non_inlinable_function_bodies_is_lazy);
306321
} else {
307-
if (Args.hasArg(OPT_experimental_skip_non_exportable_decls))
322+
if (Args.hasArg(OPT_experimental_skip_non_exportable_decls)) {
308323
Diags.diagnose(SourceLoc(), diag::ignoring_option_requires_option,
309324
"-experimental-skip-non-exportable-decls",
310325
"-enable-library-evolution");
326+
if (Opts.AllowNonResilientAccess) {
327+
Diags.diagnose(SourceLoc(), diag::warn_ignore_option_due_to_conflict,
328+
"-experimental-skip-non-exportable-decls",
329+
"-experimental-allow-non-resilient-access");
330+
}
331+
}
332+
}
333+
334+
// To allow non-resilient access from clients, it should be built from source.
335+
if (Opts.AllowNonResilientAccess &&
336+
(Opts.RequestedAction == FrontendOptions::ActionType::CompileModuleFromInterface ||
337+
Opts.RequestedAction == FrontendOptions::ActionType::TypecheckModuleFromInterface)) {
338+
Diags.diagnose(SourceLoc(), diag::warn_ignore_option_due_to_conflict,
339+
"-experimental-allow-non-resilient-access",
340+
"-compile-module-from-interface or -typecheck-module-from-interface");
341+
Opts.AllowNonResilientAccess = false;
311342
}
312343

313344
// HACK: The driver currently erroneously passes all flags to module interface

lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,11 +2123,15 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
21232123

21242124
// Propagate the typechecker's understanding of
21252125
// -experimental-skip-*-function-bodies to SIL.
2126-
Opts.SkipFunctionBodies = TCOpts.SkipFunctionBodies;
2126+
// Only set if -experimental-allow-non-resilient-access
2127+
// is not passed.
2128+
Opts.SkipFunctionBodies = FEOpts.AllowNonResilientAccess ? FunctionBodySkipping::None : TCOpts.SkipFunctionBodies;
21272129

21282130
// Propagate -experimental-skip-non-exportable-decls to SIL.
2129-
Opts.SkipNonExportableDecls = FEOpts.SkipNonExportableDecls;
2130-
2131+
// Only set if -experimental-allow-non-resilient-access is
2132+
// not passed.
2133+
Opts.SkipNonExportableDecls = FEOpts.AllowNonResilientAccess ? false : FEOpts.SkipNonExportableDecls;
2134+
21312135
// Parse the optimization level.
21322136
// Default to Onone settings if no option is passed.
21332137
Opts.OptMode = OptimizationMode::NoOptimization;

0 commit comments

Comments
 (0)