Skip to content

Commit 1e09b22

Browse files
authored
Merge pull request #71501 from DougGregor/typed-throws-as-rethrows-witness
Allow rethrow-like typed throws functions as witnesses
2 parents bf5d09b + 2370214 commit 1e09b22

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -734,14 +734,9 @@ static Expr *removeErasureToExistentialError(Expr *expr) {
734734

735735
return expr;
736736
}
737+
}
737738

738-
/// Determine whether the given function uses typed throws in a manner
739-
/// than is structurally similar to 'rethrows', e.g.,
740-
///
741-
/// \code
742-
/// func map<T, E>(_ body: (Element) throws(E) -> T) throws(E) -> [T]
743-
/// \endcode
744-
static bool isRethrowLikeTypedThrows(AbstractFunctionDecl *func) {
739+
bool swift::isRethrowLikeTypedThrows(AbstractFunctionDecl *func) {
745740
// This notion is only for compatibility in Swift 5 and is disabled
746741
// when FullTypedThrows is enabled.
747742
ASTContext &ctx = func->getASTContext();
@@ -788,6 +783,8 @@ static bool isRethrowLikeTypedThrows(AbstractFunctionDecl *func) {
788783
return true;
789784
}
790785

786+
namespace {
787+
791788
/// Determine whether the given rethrows context is only allowed to be
792789
/// rethrowing because of the historically-rethrowing behavior of
793790
/// AsyncSequence and AsyncIteratorProtocol.

lib/Sema/TypeCheckEffects.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ enum class ThrownErrorSubtyping {
4545
ThrownErrorSubtyping compareThrownErrorsForSubtyping(
4646
Type subThrownError, Type superThrownError, DeclContext *dc);
4747

48+
/// Determine whether the given function uses typed throws in a manner
49+
/// that is structurally similar to 'rethrows', e.g.,
50+
///
51+
/// \code
52+
/// func map<T, E>(_ body: (Element) throws(E) -> T) throws(E) -> [T]
53+
/// \endcode
54+
bool isRethrowLikeTypedThrows(AbstractFunctionDecl *func);
55+
4856
}
4957

5058
#endif // SWIFT_SEMA_TYPECHECKEFFECTS_H

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,11 @@ RequirementMatch swift::matchWitness(
603603
}
604604

605605
case PolymorphicEffectKind::Always:
606+
// If the witness is using typed throws in a manner that looks
607+
// like rethrows, allow it.
608+
if (isRethrowLikeTypedThrows(funcWitness))
609+
break;
610+
606611
return RequirementMatch(witness, MatchKind::RethrowsConflict);
607612
}
608613
}

test/decl/protocol/conforms/typed_throws.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,10 @@ func testAssociatedTypes() {
6969
func assocFailureType<T: FailureAssociatedType>(_ value: T, _ error: T.Failure) throws(T.Failure) {
7070
throw error
7171
}
72+
73+
// Allow a typed-throws version of a function to witness a rethrowing function.
74+
public protocol HasRethrowingMap: Sequence {
75+
func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
76+
}
77+
78+
extension Array: HasRethrowingMap {}

0 commit comments

Comments
 (0)