Skip to content

Commit 5d77258

Browse files
committed
[Typechecker] Relax the check only for non-final classes
1 parent da2c4e4 commit 5d77258

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4299,12 +4299,20 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType,
42994299
// }
43004300
// }
43014301
//
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()) {
4302+
// Note: we relax the restriction if the type we're casting to is a
4303+
// non-final class because it's possible that we might have a subclass
4304+
// that conforms to the protocol.
4305+
if (fromExistential && !toExistential) {
43064306
if (auto NTD = toType->getAnyNominal()) {
4307-
if (!isa<ProtocolDecl>(NTD)) {
4307+
bool shouldContinue = true;
4308+
4309+
// If we have a non-final class, then don't check
4310+
if (toType->is<ClassType>() && !NTD->isFinal()) {
4311+
shouldContinue = false;
4312+
}
4313+
4314+
// Otherwise, check the cast.
4315+
if (shouldContinue) {
43084316
auto protocolDecl =
43094317
dyn_cast_or_null<ProtocolDecl>(fromType->getAnyNominal());
43104318
if (protocolDecl &&

test/Constraints/patterns.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ case is B,
5555
is D,
5656
is S:
5757
()
58-
case is E: // expected-warning {{cast from 'P' to unrelated type 'E' always fails}}
58+
case is E:
5959
()
6060
default:
6161
()
@@ -69,7 +69,7 @@ case let d as D:
6969
d.d()
7070
case let s as S:
7171
s.s()
72-
case let e as E: // expected-warning {{cast from 'P' to unrelated type 'E' always fails}}
72+
case let e as E:
7373
e.e()
7474
default:
7575
()

test/stmt/errors.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,16 +209,16 @@ 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 {{immutable value 'error' was never used; consider replacing with '_' or removing it}}
213-
print("Foo")
212+
} catch let error as SR_6400_A { // Okay
213+
print(error)
214214
} catch {
215215
print("Bar")
216216
}
217217

218218
do {
219219
throw SR_6400_E.castError
220-
} catch let error as SR_6400_B { // expected-warning {{immutable value 'error' was never used; consider replacing with '_' or removing it}}
221-
print("Foo")
220+
} catch let error as SR_6400_B { // Okay
221+
print(error)
222222
} catch {
223223
print("Bar")
224224
}
@@ -230,10 +230,16 @@ protocol SR_11402_P {}
230230
class SR_11402_Superclass {}
231231
class SR_11402_Subclass: SR_11402_Superclass, SR_11402_P {}
232232

233-
func sr_11402_func(_ x: SR_11402_P) {
233+
func sr_11402_func1(_ x: SR_11402_P) {
234234
if let y = x as? SR_11402_Superclass { // Okay
235235
print(y)
236236
}
237237
}
238238

239-
sr_11402_func(SR_11402_Subclass())
239+
final class SR_11402_Final {}
240+
241+
func sr_11402_func2(_ x: SR_11402_P) {
242+
if let y = x as? SR_11402_Final { // expected-error {{cast from 'SR_11402_P' to unrelated type 'SR_11402_Final' always fails}}
243+
print(y)
244+
}
245+
}

0 commit comments

Comments
 (0)