Skip to content

Commit 6bd39db

Browse files
committed
Teach AST verifier about thrown error contexts
The AST verifier was only correctly extracting thrown error types from enclosing functions, without account for do...catch bodies. Switch it over to using ASTScope's lookup to find the innermost enclosing caught error context. Fixes a AST verifier error reported by Paul Cantrell
1 parent e2aed58 commit 6bd39db

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

lib/AST/ASTVerifier.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/AST/Initializer.h"
2929
#include "swift/AST/MacroDiscriminatorContext.h"
3030
#include "swift/AST/Module.h"
31+
#include "swift/AST/NameLookup.h"
3132
#include "swift/AST/ParameterList.h"
3233
#include "swift/AST/Pattern.h"
3334
#include "swift/AST/PrettyStackTrace.h"
@@ -1021,13 +1022,24 @@ class Verifier : public ASTWalker {
10211022

10221023
void verifyChecked(ThrowStmt *S) {
10231024
Type thrownError;
1024-
if (!Functions.empty()) {
1025-
if (auto fn = AnyFunctionRef::fromDeclContext(Functions.back()))
1026-
thrownError = fn->getThrownErrorType();
1025+
SourceLoc loc = S->getThrowLoc();
1026+
if (loc.isValid()) {
1027+
auto catchNode = ASTScope::lookupCatchNode(getModuleContext(), loc);
1028+
1029+
if (!catchNode) {
1030+
Out << "No catch context for throw statement\n";
1031+
abort();
1032+
}
1033+
1034+
if (auto thrown = catchNode.getThrownErrorTypeInContext(Ctx)) {
1035+
thrownError = *thrown;
1036+
} else {
1037+
thrownError = Ctx.getNeverType();
1038+
}
1039+
} else {
1040+
return;
10271041
}
10281042

1029-
if (!thrownError)
1030-
thrownError = checkExceptionTypeExists("throw expression");
10311043
checkSameType(S->getSubExpr()->getType(), thrownError, "throw operand");
10321044
verifyCheckedBase(S);
10331045
}

test/SILGen/typed_throws.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,23 @@ open class MyClass {
130130
func f() throws { }
131131
}
132132

133+
134+
struct Foo: Error { }
135+
struct Bar: Error { }
136+
137+
// CHECK-LABEL: sil hidden [ossa] @$s12typed_throws0B22DifferentFromEnclosingyyAA3FooVYKF : $@convention(thin) () -> @error Foo
138+
func throwsDifferentFromEnclosing() throws(Foo) {
139+
do {
140+
throw Bar()
141+
} catch {
142+
print("Bar was barred")
143+
}
144+
145+
// CHECK: throw [[ERROR:%.*]] : $Foo
146+
throw Foo()
147+
}
148+
149+
133150
// CHECK-LABEL: sil_vtable MySubclass {
134151
// CHECK-NEXT: #MyClass.init!allocator: <E where E : Error> (MyClass.Type) -> (() throws(E) -> ()) throws(E) -> MyClass : @$s12typed_throws10MySubclassC4bodyACyyxYKXE_txYKcs5ErrorRzlufC [override]
135152
// CHECK-NEXT: #MyClass.f: (MyClass) -> () throws -> () : @$s12typed_throws10MySubclassC1fyyAA0C5ErrorOYKFAA0C5ClassCADyyKFTV [override]

0 commit comments

Comments
 (0)