Skip to content

Commit 1bc028e

Browse files
authored
Merge pull request swiftlang#32091 from hamishknight/standard-error
2 parents e1eb27a + ab6c15f commit 1bc028e

File tree

5 files changed

+34
-28
lines changed

5 files changed

+34
-28
lines changed

include/swift/Frontend/Frontend.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -642,10 +642,11 @@ class CompilerInstance {
642642
public:
643643
void freeASTContext();
644644

645-
private:
646-
/// Load stdlib & return true if should continue, i.e. no error
647-
bool loadStdlib();
645+
/// If an implicit standard library import is expected, loads the standard
646+
/// library, returning \c false if we should continue, i.e. no error.
647+
bool loadStdlibIfNeeded();
648648

649+
private:
649650
/// Retrieve a description of which modules should be implicitly imported.
650651
ImplicitImportInfo getImplicitImportInfo() const;
651652

lib/AST/ASTVerifier.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2734,8 +2734,8 @@ class Verifier : public ASTWalker {
27342734
const DeclContext *DC = GTPD->getDeclContext();
27352735

27362736
// Skip verification of deserialized generic param decls that have the
2737-
// the file set as their parent. This happens when they have not yet had
2738-
// their correct parent set.
2737+
// file set as their parent. This happens when they have not yet had their
2738+
// correct parent set.
27392739
// FIXME: This is a hack to workaround the fact that we don't necessarily
27402740
// parent a GenericTypeParamDecl if we just deserialize its type.
27412741
if (auto *fileDC = dyn_cast<FileUnit>(DC)) {

lib/Frontend/Frontend.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -740,17 +740,6 @@ void CompilerInstance::performSemaUpTo(SourceFile::ASTStage_t LimitStage,
740740
ModuleDecl *mainModule = getMainModule();
741741
Context->LoadedModules[mainModule->getName()] = mainModule;
742742

743-
// If we aren't in a parse-only context, load the standard library.
744-
if (LimitStage > SourceFile::Unprocessed &&
745-
Invocation.getImplicitStdlibKind() == ImplicitStdlibKind::Stdlib
746-
&& !loadStdlib()) {
747-
// If we failed to load the stdlib, mark the main module as having
748-
// "failed to load", as it will contain no files.
749-
// FIXME: We need to better handle a missing stdlib.
750-
mainModule->setFailedToLoad();
751-
return;
752-
}
753-
754743
// Make sure the main file is the first file in the module, so do this now.
755744
if (MainBufferID != NO_SUCH_BUFFER) {
756745
auto *mainFile = createSourceFileForMainModule(
@@ -813,23 +802,27 @@ void CompilerInstance::performSemaUpTo(SourceFile::ASTStage_t LimitStage,
813802
finishTypeChecking();
814803
}
815804

816-
bool CompilerInstance::loadStdlib() {
805+
bool CompilerInstance::loadStdlibIfNeeded() {
806+
// If we aren't expecting an implicit stdlib import, there's nothing to do.
807+
if (getImplicitImportInfo().StdlibKind != ImplicitStdlibKind::Stdlib)
808+
return false;
809+
817810
FrontendStatsTracer tracer(getStatsReporter(), "load-stdlib");
818-
ModuleDecl *M = Context->getStdlibModule(true);
811+
ModuleDecl *M = Context->getStdlibModule(/*loadIfAbsent*/ true);
819812

820813
if (!M) {
821814
Diagnostics.diagnose(SourceLoc(), diag::error_stdlib_not_found,
822815
Invocation.getTargetTriple());
823-
return false;
816+
return true;
824817
}
825818

826-
// If we failed to load, we should have already diagnosed
819+
// If we failed to load, we should have already diagnosed.
827820
if (M->failedToLoad()) {
828821
assert(Diagnostics.hadAnyError() &&
829822
"Module failed to load but nothing was diagnosed?");
830-
return false;
823+
return true;
831824
}
832-
return true;
825+
return false;
833826
}
834827

835828
bool CompilerInstance::loadPartialModulesAndImplicitImports() {

lib/FrontendTool/FrontendTool.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,17 @@ static bool performCompile(CompilerInstance &Instance,
12501250
if (Invocation.getInputKind() == InputFileKind::LLVM)
12511251
return compileLLVMIR(Instance);
12521252

1253+
// If we aren't in a parse-only context and expect an implicit stdlib import,
1254+
// load in the standard library. If we either fail to find it or encounter an
1255+
// error while loading it, bail early. Continuing the compilation will at best
1256+
// trigger a bunch of other errors due to the stdlib being missing, or at
1257+
// worst crash downstream as many call sites don't currently handle a missing
1258+
// stdlib.
1259+
if (!FrontendOptions::shouldActionOnlyParse(Action)) {
1260+
if (Instance.loadStdlibIfNeeded())
1261+
return true;
1262+
}
1263+
12531264
if (FrontendOptions::shouldActionOnlyParse(Action)) {
12541265
// Disable delayed parsing of type and function bodies when we've been
12551266
// asked to dump the resulting AST.

lib/IDE/CompletionInstance.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -527,15 +527,16 @@ bool CompletionInstance::performNewOperation(
527527
}
528528
registerIDERequestFunctions(CI.getASTContext().evaluator);
529529

530-
CI.performParseAndResolveImportsOnly();
531-
532-
// If we didn't create a source file for completion, bail. This can happen
533-
// if for example we fail to load the stdlib.
534-
auto completionFile = CI.getCodeCompletionFile();
535-
if (!completionFile)
530+
// If we're expecting a standard library, but there either isn't one, or it
531+
// failed to load, let's bail early and hand back an empty completion
532+
// result to avoid any downstream crashes.
533+
if (CI.loadStdlibIfNeeded())
536534
return true;
537535

536+
CI.performParseAndResolveImportsOnly();
537+
538538
// If we didn't find a code completion token, bail.
539+
auto completionFile = CI.getCodeCompletionFile();
539540
auto *state = completionFile.get()->getDelayedParserState();
540541
if (!state->hasCodeCompletionDelayedDeclState())
541542
return true;

0 commit comments

Comments
 (0)