Skip to content

Commit 956c330

Browse files
committed
[Constraint solver] Encode thrown error type in references to subscripts
A reference to a subscript (whether instance or static) produces a function type, which is then applied as part of an application constraint. Make sure that we encode whether the subscript can throw, and the thrown error type if present, in that function type. This lets us correctly treat subscripts as a potential throw sites.
1 parent 8ad137f commit 956c330

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2674,6 +2674,18 @@ ConstraintSystem::getTypeOfMemberReference(
26742674
[&](Type type) { return openType(type, replacements, locator); });
26752675
}
26762676
} else {
2677+
// Figure out the effect information for the reference.
2678+
FunctionType::ExtInfo info;
2679+
auto storage = cast<AbstractStorageDecl>(value);
2680+
2681+
// If the storage has a throwing getter, record that in the type.
2682+
if (auto effectfulGetter = storage->getEffectfulGetAccessor()) {
2683+
if (effectfulGetter->hasThrows()) {
2684+
Type thrownErrorType = effectfulGetter->getThrownInterfaceType();
2685+
info = info.withThrows(true, thrownErrorType);
2686+
}
2687+
}
2688+
26772689
// For a property, build a type (Self) -> PropType.
26782690
// For a subscript, build a type (Self) -> (Indices...) -> ElementType.
26792691
//
@@ -2687,8 +2699,7 @@ ConstraintSystem::getTypeOfMemberReference(
26872699

26882700
auto indices = subscript->getInterfaceType()
26892701
->castTo<AnyFunctionType>()->getParams();
2690-
// FIXME: Verify ExtInfo state is correct, not working by accident.
2691-
FunctionType::ExtInfo info;
2702+
26922703
refType = FunctionType::get(indices, elementTy, info);
26932704
} else {
26942705
// Delay the adjustment for preconcurrency until after we've formed
@@ -2720,8 +2731,6 @@ ConstraintSystem::getTypeOfMemberReference(
27202731
}
27212732
FunctionType::Param selfParam(selfTy, Identifier(), selfFlags);
27222733

2723-
// FIXME: Verify ExtInfo state is correct, not working by accident.
2724-
FunctionType::ExtInfo info;
27252734
openedType = FunctionType::get({selfParam}, refType, info);
27262735
}
27272736
assert(!openedType->hasTypeParameter());

test/stmt/typed_throws.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,19 @@ func testDoCatchErrorTypedInClosure(cond: Bool) {
192192
}
193193
}
194194

195-
func testDoCatchInClosure(cond: Bool) {
195+
struct ThrowingMembers {
196+
subscript(i: Int) -> Int {
197+
get throws(MyError) { i }
198+
}
199+
}
200+
201+
struct ThrowingStaticSubscript {
202+
static subscript(i: Int) -> Int {
203+
get throws(MyError) { i }
204+
}
205+
}
206+
207+
func testDoCatchInClosure(cond: Bool, x: ThrowingMembers) {
196208
apply {
197209
do {
198210
_ = try doSomething()
@@ -233,4 +245,21 @@ func testDoCatchInClosure(cond: Bool) {
233245
let _: MyError = error
234246
}
235247
}
248+
249+
// Subscripts as potential throw sites
250+
apply {
251+
do {
252+
_ = try x[5]
253+
} catch {
254+
let _: MyError = error
255+
}
256+
}
257+
258+
apply {
259+
do {
260+
_ = try ThrowingStaticSubscript[5]
261+
} catch {
262+
let _: MyError = error
263+
}
264+
}
236265
}

0 commit comments

Comments
 (0)