Skip to content

Commit 920e4bb

Browse files
authored
Merge pull request #9009 from DougGregor/casts-and-errors-4.0
[4.0] Yet more targeted fixes
2 parents 3887db1 + 4e9f737 commit 920e4bb

File tree

4 files changed

+25
-7
lines changed

4 files changed

+25
-7
lines changed

lib/SILOptimizer/Utils/Local.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,9 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
16611661
if ((ConvTy == DestTy || DestTy.isExactSuperclassOf(ConvTy))) {
16621662
CastedValue = SILValue(
16631663
(ConvTy == DestTy) ? NewI : Builder.createUpcast(Loc, NewAI, DestTy));
1664+
} else if (ConvTy.isExactSuperclassOf(DestTy)) {
1665+
CastedValue = SILValue(
1666+
Builder.createUnconditionalCheckedCast(Loc, NewAI, DestTy));
16641667
} else if (ConvTy.getSwiftRValueType() ==
16651668
getNSBridgedClassOfCFClass(M.getSwiftModule(),
16661669
DestTy.getSwiftRValueType()) ||
@@ -1673,8 +1676,7 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
16731676
} else {
16741677
llvm_unreachable(
16751678
"Destination should have the same type, be bridgeable CF "
1676-
"type or be a superclass "
1677-
"of the source operand");
1679+
"type or be a superclass/subclass of the source operand");
16781680
}
16791681
NewI = Builder.createStore(Loc, CastedValue, Dest,
16801682
StoreOwnershipQualifier::Unqualified);

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/SILOptimizer/bridged_casts_folding.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,4 +900,16 @@ public func testCondCastSwiftToCFSetInt() -> CFSet? {
900900
return setOpt
901901
}
902902

903+
public class NSObjectSubclass : NSObject { }
903904

905+
var anyHashable: AnyHashable = 0
906+
907+
// CHECK-LABEL: _T021bridged_casts_folding29testUncondCastSwiftToSubclassAA08NSObjectI0CyF
908+
// CHECK: [[GLOBAL:%[0-9]+]] = global_addr @_T021bridged_casts_folding11anyHashables03AnyE0Vv
909+
// CHECK: function_ref @_T0s11AnyHashableV10FoundationE19_bridgeToObjectiveCSo8NSObjectCyF
910+
// CHECK-NEXT: apply
911+
// CHECK-NEXT: unconditional_checked_cast {{%.*}} : $NSObject to $NSObjectSubclass
912+
@inline(never)
913+
public func testUncondCastSwiftToSubclass() -> NSObjectSubclass {
914+
return anyHashable as! NSObjectSubclass
915+
}

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)