[Frontend] Diagnose rather than exit/assert on experimental features

Diagnose rather than exit when using experimental features that cannot
be enabled in production. Also diagnose if using a compiler without
`SwiftCompilerSources` when enabling embedded.

This is especially important for long-running services like sourcekitd,
which shouldn't exit just because an invalid argument was passed.

Resolves rdar://119724074.
This commit is contained in:
Ben Barham
2024-01-02 12:41:59 -08:00
parent 9019d07fd7
commit a6c8bf3818
2 changed files with 18 additions and 7 deletions

View File

@@ -845,13 +845,15 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
if (auto feature = getExperimentalFeature(value)) {
#ifdef NDEBUG
if (!isFeatureAvailableInProduction(*feature)) {
llvm::errs() << "error: experimental feature '" << A->getValue()
<< "' cannot be enabled in a production compiler\n";
exit(1);
Diags.diagnose(SourceLoc(), diag::experimental_not_supported_in_production,
A->getValue());
HadError = true;
} else {
Opts.Features.insert(*feature);
}
#endif
#else
Opts.Features.insert(*feature);
#endif
}
// Hack: In order to support using availability macros in SPM packages, we
@@ -1368,12 +1370,15 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.BypassResilienceChecks |= Args.hasArg(OPT_bypass_resilience);
if (Opts.hasFeature(Feature::Embedded)) {
assert(swiftModulesInitialized() && "no SwiftCompilerSources");
Opts.UnavailableDeclOptimizationMode = UnavailableDeclOptimization::Complete;
Opts.DisableImplicitStringProcessingModuleImport = true;
Opts.DisableImplicitConcurrencyModuleImport = true;
if (!swiftModulesInitialized()) {
Diags.diagnose(SourceLoc(), diag::no_swift_sources_with_embedded);
HadError = true;
}
if (FrontendOpts.EnableLibraryEvolution) {
Diags.diagnose(SourceLoc(), diag::evolution_with_embedded);
HadError = true;