Skip to content

Commit 148cd6a

Browse files
author
Zak Kent
committed
[Immediate] [Sema] Implemented Lazy Type Checking
Implements lazy type checking in Swift Immediate mode, allowing functions to be type-checked as they are executed.
1 parent 17fedab commit 148cd6a

File tree

8 files changed

+27
-15
lines changed

8 files changed

+27
-15
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,8 +2997,7 @@ class TypeCheckSourceFileRequest
29972997
friend SimpleRequest;
29982998

29992999
// Evaluation.
3000-
evaluator::SideEffect evaluate(Evaluator &evaluator, SourceFile *SF,
3001-
bool CheckFunctionBodies = true) const;
3000+
evaluator::SideEffect evaluate(Evaluator &evaluator, SourceFile *SF) const;
30023001

30033002
public:
30043003
// Separate caching.

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,9 @@ namespace swift {
799799

800800
/// See \ref FrontendOptions.PrintFullConvention
801801
bool PrintFullConvention = false;
802+
803+
/// Defer typechecking of declarations to their use at runtime
804+
bool DeferToRuntime = false;
802805
};
803806

804807
/// Options for controlling the behavior of the Clang importer.

include/swift/SIL/SILDeclRef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ struct SILDeclRef {
294294
bool hasAutoClosureExpr() const;
295295
bool hasFuncDecl() const;
296296

297-
ValueDecl *getDecl() const { return loc.get<ValueDecl *>(); }
297+
ValueDecl *getDecl() const { return loc.dyn_cast<ValueDecl *>(); }
298298
AbstractClosureExpr *getAbstractClosureExpr() const {
299299
return loc.dyn_cast<AbstractClosureExpr *>();
300300
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,9 @@ static bool ParseTypeCheckerArgs(TypeCheckerOptions &Opts, ArgList &Args,
14241424
if (Args.getLastArg(OPT_solver_disable_shrink))
14251425
Opts.SolverDisableShrink = true;
14261426

1427+
if (FrontendOpts.RequestedAction == FrontendOptions::ActionType::Immediate)
1428+
Opts.DeferToRuntime = true;
1429+
14271430
Opts.DebugGenericSignatures |= Args.hasArg(OPT_debug_generic_signatures);
14281431

14291432
return HadError;

lib/FrontendTool/FrontendTool.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -843,10 +843,6 @@ bool swift::performCompileStepsPostSema(CompilerInstance &Instance,
843843
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode();
844844
SILOptions SILOpts = getSILOptions(PSPs);
845845
IRGenOptions irgenOpts = Invocation.getIRGenOptions();
846-
if (Invocation.getFrontendOptions().RequestedAction ==
847-
FrontendOptions::ActionType::Immediate) {
848-
return RunImmediatelyFromAST(Instance) != -1;
849-
}
850846
auto SM = performASTLowering(mod, Instance.getSILTypes(), SILOpts,
851847
&irgenOpts);
852848
return performCompileStepsPostSILGen(Instance, std::move(SM), mod, PSPs,
@@ -1368,13 +1364,15 @@ static bool performAction(CompilerInstance &Instance,
13681364
[](CompilerInstance &Instance) {
13691365
return Instance.getASTContext().hadError();
13701366
});
1367+
case FrontendOptions::ActionType::Immediate: {
1368+
return RunImmediatelyFromAST(Instance) != -1;
1369+
}
13711370
case FrontendOptions::ActionType::EmitSILGen:
13721371
case FrontendOptions::ActionType::EmitSIBGen:
13731372
case FrontendOptions::ActionType::EmitSIL:
13741373
case FrontendOptions::ActionType::EmitSIB:
13751374
case FrontendOptions::ActionType::EmitModuleOnly:
13761375
case FrontendOptions::ActionType::MergeModules:
1377-
case FrontendOptions::ActionType::Immediate:
13781376
case FrontendOptions::ActionType::EmitAssembly:
13791377
case FrontendOptions::ActionType::EmitIRGen:
13801378
case FrontendOptions::ActionType::EmitIR:

lib/Immediate/Immediate.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,15 @@ class SwiftMaterializationUnit : public llvm::orc::MaterializationUnit {
596596
SILRefsToEmit Refs;
597597
for (auto &Sym : R->getRequestedSymbols()) {
598598
const auto &Source = Sources.storage->find(*Sym)->getValue();
599-
Refs.push_back(Source.getSILDeclRef());
599+
auto Ref = Source.getSILDeclRef();
600+
if (auto *AFD = Ref.getAbstractFunctionDecl()) {
601+
AFD->getTypecheckedBody();
602+
if (CI.getASTContext().hadError()) {
603+
R->failMaterialization();
604+
return;
605+
}
606+
}
607+
Refs.push_back(std::move(Ref));
600608
}
601609
auto SM = performASTLowering(CI, std::move(Refs));
602610
runSILDiagnosticPasses(*SM);
@@ -888,9 +896,11 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
888896
}
889897

890898
int swift::RunImmediatelyFromAST(CompilerInstance &CI) {
891-
899+
CI.performSema();
892900
auto &Context = CI.getASTContext();
893-
901+
if (Context.hadError()) {
902+
return -1;
903+
}
894904
const auto &Invocation = CI.getInvocation();
895905
const auto &FrontendOpts = Invocation.getFrontendOptions();
896906

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ bool SILDeclRef::isSetter() const {
734734
}
735735

736736
AbstractFunctionDecl *SILDeclRef::getAbstractFunctionDecl() const {
737-
return dyn_cast<AbstractFunctionDecl>(getDecl());
737+
return dyn_cast_or_null<AbstractFunctionDecl>(getDecl());
738738
}
739739

740740
bool SILDeclRef::isInitAccessor() const {

lib/Sema/TypeChecker.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,7 @@ void swift::performTypeChecking(SourceFile &SF) {
260260
}
261261

262262
evaluator::SideEffect
263-
TypeCheckSourceFileRequest::evaluate(Evaluator &eval, SourceFile *SF,
264-
bool CheckFunctionBodies) const {
263+
TypeCheckSourceFileRequest::evaluate(Evaluator &eval, SourceFile *SF) const {
265264
assert(SF && "Source file cannot be null!");
266265
assert(SF->ASTStage != SourceFile::TypeChecked &&
267266
"Should not be re-typechecking this file!");
@@ -307,7 +306,7 @@ TypeCheckSourceFileRequest::evaluate(Evaluator &eval, SourceFile *SF,
307306
}
308307
}
309308
}
310-
if (CheckFunctionBodies) {
309+
if (!Ctx.TypeCheckerOpts.DeferToRuntime) {
311310
typeCheckDelayedFunctions(*SF);
312311
}
313312
}

0 commit comments

Comments
 (0)