Skip to content

Commit da2c4e4

Browse files
committed
[Typechecker] Relax existential to concrete type cast check for classes
1 parent 8fcc94f commit da2c4e4

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4298,7 +4298,11 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
42984298
// print("Caught bar error")
42994299
// }
43004300
// }
4301-
if (fromExistential) {
4301+
//
4302+
// Note: we relax the restriction if the type we're casting to is a class
4303+
// because it's possible that we might have a subclass that conforms to
4304+
// the protocol.
4305+
if (fromExistential && !toType->hasReferenceSemantics()) {
43024306
if (auto NTD = toType->getAnyNominal()) {
43034307
if (!isa<ProtocolDecl>(NTD)) {
43044308
auto protocolDecl =

test/stmt/errors.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ class SR_6400_B: SR_6400_FakeApplicationDelegate & Error {}
209209
func sr_6400_4() {
210210
do {
211211
throw SR_6400_E.castError
212-
} catch let error as SR_6400_A { // expected-warning {{cast from 'Error' to unrelated type 'SR_6400_A' always fails}} // expected-warning {{immutable value 'error' was never used; consider replacing with '_' or removing it}}
212+
} catch let error as SR_6400_A { // expected-warning {{immutable value 'error' was never used; consider replacing with '_' or removing it}}
213213
print("Foo")
214214
} catch {
215215
print("Bar")
@@ -223,3 +223,17 @@ func sr_6400_4() {
223223
print("Bar")
224224
}
225225
}
226+
227+
// SR-11402
228+
229+
protocol SR_11402_P {}
230+
class SR_11402_Superclass {}
231+
class SR_11402_Subclass: SR_11402_Superclass, SR_11402_P {}
232+
233+
func sr_11402_func(_ x: SR_11402_P) {
234+
if let y = x as? SR_11402_Superclass { // Okay
235+
print(y)
236+
}
237+
}
238+
239+
sr_11402_func(SR_11402_Subclass())

0 commit comments

Comments
 (0)