Skip to content

Commit ebcb438

Browse files
committed
[Type checker] Fix rethrow checking with a single argument label harder.
My original fix for rdar://problem/31794932 didn't work for generic functions because it was checking in the unsubstituted interface type. Check structurally instead. Fixes rdar://problem/31794932. (cherry picked from commit dd96aee)
1 parent 3887db1 commit ebcb438

File tree

2 files changed

+9
-5
lines changed

2 files changed

+9
-5
lines changed

lib/Sema/TypeCheckError.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -665,18 +665,17 @@ class ApplyClassifier {
665665
Classification classifyRethrowsArgument(Expr *arg, Type paramType) {
666666
arg = arg->getValueProvidingExpr();
667667

668-
// If the parameter was a tuple, try to look through the various
669-
// tuple operations.
670-
if (auto paramTupleType = paramType->getAs<TupleType>()) {
668+
// If the parameter was structurally a tuple, try to look through the
669+
// various tuple operations.
670+
if (auto paramTupleType = dyn_cast<TupleType>(paramType.getPointer())) {
671671
if (auto tuple = dyn_cast<TupleExpr>(arg)) {
672672
return classifyTupleRethrowsArgument(tuple, paramTupleType);
673673
} else if (auto shuffle = dyn_cast<TupleShuffleExpr>(arg)) {
674674
return classifyShuffleRethrowsArgument(shuffle, paramTupleType);
675675
}
676676

677677
int scalarElt = paramTupleType->getElementForScalarInit();
678-
if (scalarElt < 0 ||
679-
!paramTupleType->getElementType(scalarElt)->isEqual(arg->getType())) {
678+
if (scalarElt < 0) {
680679
// Otherwise, we're passing an opaque tuple expression, and we
681680
// should treat it as contributing to 'rethrows' if the original
682681
// parameter type included a throwing function type.

test/decl/func/rethrows.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@ func throwWhileGettingFoo() throws -> Foo.Type { return Foo.self }
480480
// <rdar://problem/31794932> [Source compatibility] Call to sort(by):) can throw, but is not marked with 'try'
481481
func doRethrow(fn: (Int, Int) throws -> Int) rethrows { }
482482

483+
struct DoRethrowGeneric<T> {
484+
func method(fn: (T, T) throws -> T) rethrows { }
485+
}
486+
483487
func testDoRethrow() {
484488
doRethrow(fn:) { (a, b) in return a }
489+
DoRethrowGeneric<Int>().method(fn:) { (a, b) in return a }
485490
}

0 commit comments

Comments
 (0)