mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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.
This commit is contained in:
@@ -2674,6 +2674,18 @@ ConstraintSystem::getTypeOfMemberReference(
|
||||
[&](Type type) { return openType(type, replacements, locator); });
|
||||
}
|
||||
} else {
|
||||
// Figure out the effect information for the reference.
|
||||
FunctionType::ExtInfo info;
|
||||
auto storage = cast<AbstractStorageDecl>(value);
|
||||
|
||||
// If the storage has a throwing getter, record that in the type.
|
||||
if (auto effectfulGetter = storage->getEffectfulGetAccessor()) {
|
||||
if (effectfulGetter->hasThrows()) {
|
||||
Type thrownErrorType = effectfulGetter->getThrownInterfaceType();
|
||||
info = info.withThrows(true, thrownErrorType);
|
||||
}
|
||||
}
|
||||
|
||||
// For a property, build a type (Self) -> PropType.
|
||||
// For a subscript, build a type (Self) -> (Indices...) -> ElementType.
|
||||
//
|
||||
@@ -2687,8 +2699,7 @@ ConstraintSystem::getTypeOfMemberReference(
|
||||
|
||||
auto indices = subscript->getInterfaceType()
|
||||
->castTo<AnyFunctionType>()->getParams();
|
||||
// FIXME: Verify ExtInfo state is correct, not working by accident.
|
||||
FunctionType::ExtInfo info;
|
||||
|
||||
refType = FunctionType::get(indices, elementTy, info);
|
||||
} else {
|
||||
// Delay the adjustment for preconcurrency until after we've formed
|
||||
@@ -2720,8 +2731,6 @@ ConstraintSystem::getTypeOfMemberReference(
|
||||
}
|
||||
FunctionType::Param selfParam(selfTy, Identifier(), selfFlags);
|
||||
|
||||
// FIXME: Verify ExtInfo state is correct, not working by accident.
|
||||
FunctionType::ExtInfo info;
|
||||
openedType = FunctionType::get({selfParam}, refType, info);
|
||||
}
|
||||
assert(!openedType->hasTypeParameter());
|
||||
|
||||
@@ -192,7 +192,19 @@ func testDoCatchErrorTypedInClosure(cond: Bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func testDoCatchInClosure(cond: Bool) {
|
||||
struct ThrowingMembers {
|
||||
subscript(i: Int) -> Int {
|
||||
get throws(MyError) { i }
|
||||
}
|
||||
}
|
||||
|
||||
struct ThrowingStaticSubscript {
|
||||
static subscript(i: Int) -> Int {
|
||||
get throws(MyError) { i }
|
||||
}
|
||||
}
|
||||
|
||||
func testDoCatchInClosure(cond: Bool, x: ThrowingMembers) {
|
||||
apply {
|
||||
do {
|
||||
_ = try doSomething()
|
||||
@@ -233,4 +245,21 @@ func testDoCatchInClosure(cond: Bool) {
|
||||
let _: MyError = error
|
||||
}
|
||||
}
|
||||
|
||||
// Subscripts as potential throw sites
|
||||
apply {
|
||||
do {
|
||||
_ = try x[5]
|
||||
} catch {
|
||||
let _: MyError = error
|
||||
}
|
||||
}
|
||||
|
||||
apply {
|
||||
do {
|
||||
_ = try ThrowingStaticSubscript[5]
|
||||
} catch {
|
||||
let _: MyError = error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user