Skip to content

Commit ff38f37

Browse files
committed
SILGen: Skip function bodies with errors in lazy typechecking mode.
The SILGen pipeline expects function bodies to have been succesfully type checked and will usually crash if it attempts to emit SIL for a function that has errors. To avoid crashing, cause function body typechecking to happen earlier in lazy typechecking mode and then skip functions whenever any errors have been encountered. Resolves rdar://130777647.
1 parent 8a40393 commit ff38f37

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

lib/SILGen/SILGen.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,28 @@ static SILFunction *getFunctionToInsertAfter(SILGenModule &SGM,
647647
}
648648

649649
static bool shouldEmitFunctionBody(const AbstractFunctionDecl *AFD) {
650-
return AFD->hasBody() && !AFD->isBodySkipped();
650+
if (!AFD->hasBody())
651+
return false;
652+
653+
if (AFD->isBodySkipped())
654+
return false;
655+
656+
auto &ctx = AFD->getASTContext();
657+
if (ctx.TypeCheckerOpts.EnableLazyTypecheck) {
658+
// Force the function body to be type-checked and then skip it if there
659+
// have been any errors.
660+
(void)AFD->getTypecheckedBody();
661+
662+
// FIXME: Only skip bodies that contain type checking errors.
663+
// It would be ideal to only skip the function body if it is specifically
664+
// the source of an error. However, that information isn't available today
665+
// so instead we avoid emitting all function bodies as soon as any error is
666+
// encountered.
667+
if (ctx.hadError())
668+
return false;
669+
}
670+
671+
return true;
651672
}
652673

653674
static bool isEmittedOnDemand(SILModule &M, SILDeclRef constant) {

test/SILGen/lazy_typecheck_errors.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,8 @@ public class DerivedFromNonExistent: NonExistent {
6161

6262
public func method() {}
6363
}
64+
65+
@inlinable public func hasErrorInBody() {
66+
nonExistent()
67+
// expected-error@-1 {{cannot find 'nonExistent' in scope}}
68+
}

0 commit comments

Comments
 (0)