@@ -113,10 +113,10 @@ func protocol_concrete_casts(_ p1: P1, p2: P2, p12: P1 & P2) {
113
113
114
114
_ = p2 as! S1 // expected-warning {{cast from 'P2' to unrelated type 'S1' always fails}}
115
115
116
- _ = p12 as! S1
117
- _ = p12 as! S2
116
+ _ = p12 as! S1 // expected-warning {{cast from 'P1 & P2' to unrelated type 'S1' always fails}}
117
+ _ = p12 as! S2 // expected-warning {{cast from 'P1 & P2' to unrelated type 'S2' always fails}}
118
118
_ = p12 as! S12
119
- _ = p12 as! S3
119
+ _ = p12 as! S3 // expected-warning {{cast from 'P1 & P2' to unrelated type 'S3' always fails}}
120
120
121
121
// Type queries.
122
122
var _: Bool = p1 is S1
@@ -128,10 +128,10 @@ func protocol_concrete_casts(_ p1: P1, p2: P2, p12: P1 & P2) {
128
128
129
129
var _: Bool = p2 is S1 // expected-warning {{cast from 'P2' to unrelated type 'S1' always fails}}
130
130
131
- var _: Bool = p12 is S1
132
- var _: Bool = p12 is S2
131
+ var _: Bool = p12 is S1 // expected-warning {{cast from 'P1 & P2' to unrelated type 'S1' always fails}}
132
+ var _: Bool = p12 is S2 // expected-warning {{cast from 'P1 & P2' to unrelated type 'S2' always fails}}
133
133
var _: Bool = p12 is S12
134
- var _: Bool = p12 is S3
134
+ var _: Bool = p12 is S3 // expected-warning {{cast from 'P1 & P2' to unrelated type 'S3' always fails}}
135
135
}
136
136
137
137
func conditional_cast( _ b: B ) -> D ? {
@@ -372,6 +372,26 @@ enum ConcreteA: EventA {
372
372
}
373
373
}
374
374
375
+ protocol ProtocolP1 { }
376
+ protocol ProtocolQ1 { }
377
+ typealias Composition = ProtocolP1 & ProtocolQ1
378
+
379
+ protocol ProtocolP { }
380
+ protocol ProtocolQ { }
381
+
382
+ class ConcreteP : ProtocolP { }
383
+ class ConcreteQ : ProtocolQ { }
384
+ class ConcretePQ : ProtocolP , ProtocolQ { }
385
+ class ConcreteCPQ : ConcreteP , ProtocolQ { }
386
+
387
+ class ConcreteP1 : ProtocolP1 { }
388
+ class ConcretePQ1 : ProtocolP1 , ProtocolQ1 { }
389
+
390
+ class ConcretePPQ1 : ProtocolP , ProtocolP1 , ProtocolQ1 { }
391
+ class NotConforms { }
392
+ struct StructNotComforms { }
393
+ final class NotConformsFinal { }
394
+
375
395
func tests_SR13088_false_positive_always_fail_casts( ) {
376
396
// SR-13081
377
397
let x : JSON = [ 4 ] // [4]
@@ -403,3 +423,20 @@ func tests_SR13088_false_positive_always_fail_casts() {
403
423
}
404
424
}
405
425
}
426
+
427
+ // Protocol composition
428
+ func protocol_composition( _ c: ProtocolP & ProtocolQ , _ c1: ProtocolP & Composition ) {
429
+ _ = c as? ConcretePQ // Ok
430
+ _ = c as? ConcreteCPQ // Ok
431
+ _ = c as? ConcreteP // Ok
432
+ _ = c as? NotConforms // Ok
433
+ _ = c as? StructNotComforms // expected-warning {{cast from 'ProtocolP & ProtocolQ' to unrelated type 'StructNotComforms' always fails}}
434
+ _ = c as? NotConformsFinal // expected-warning {{cast from 'ProtocolP & ProtocolQ' to unrelated type 'NotConformsFinal' always fails}}
435
+ _ = c1 as? ConcreteP // Ok
436
+ _ = c1 as? ConcreteP1 // OK
437
+ _ = c1 as? ConcretePQ1 // OK
438
+ _ = c1 as? ConcretePPQ1 // Ok
439
+ _ = c1 as? NotConforms // Ok
440
+ _ = c1 as? StructNotComforms // expected-warning {{cast from 'ProtocolP & Composition' (aka 'ProtocolP & ProtocolP1 & ProtocolQ1') to unrelated type 'StructNotComforms' always fails}}
441
+ _ = c1 as? NotConformsFinal // expected-warning {{cast from 'ProtocolP & Composition' (aka 'ProtocolP & ProtocolP1 & ProtocolQ1') to unrelated type 'NotConformsFinal' always fails}}
442
+ }
0 commit comments