File: as_coerce.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (216 lines) | stat: -rw-r--r-- 9,787 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// RUN: %target-typecheck-verify-swift -enable-objc-interop

// Test the use of 'as' for type coercion (which requires no checking).
@objc protocol P1 {
  func foo()
}

class A : P1 { 
  @objc func foo() { }
}
@objc class B : A { 
  func bar() { }
}

func doFoo() {}

func test_coercion(_ a: A, b: B) {
  // Coercion to a protocol type
  let x = a as P1
  x.foo()
  // Coercion to a superclass type
  let y = b as A
  y.foo()
}

class C : B { }

class D : C { }


func prefer_coercion(_ c: inout C) {
  let d = c as! D
  c = d
}

// Coerce literals
var i32 = 1 as Int32
var i8 = -1 as Int8

// Coerce to a superclass with generic parameter inference
class C1<T> { 
  func f(_ x: T) { }
}
class C2<T> : C1<Int> { }

var c2 = C2<()>()
var c1 = c2 as C1
c1.f(5)

@objc protocol P {}
class CC : P {}
let cc: Any = CC()
if cc is P {
  doFoo()
}
if let p = cc as? P {
  doFoo()
  _ = p
}

// Test that 'as?' coercion fails.
let strImplicitOpt: String! = nil
_ = strImplicitOpt as? String // expected-warning{{conditional downcast from 'String?' to 'String' does nothing}}{{19-30=}}

class C3 {}
class C4 : C3 {}
class C5 {}

var c: AnyObject = C3()

// XXX TODO: Constant-folding should generate an error about 'C3' not being convertible to 'C4'
//if let castX = c as! C4? {}

// XXX TODO: Only suggest replacing 'as' with 'as!' if it would fix the error.
C3() as C4 // expected-error {{'C3' is not convertible to 'C4'}} 
// expected-note@-1 {{did you mean to use 'as!' to force downcast?}} {{6-8=as!}}
C3() as C5 // expected-error {{cannot convert value of type 'C3' to type 'C5' in coercion}}

// Diagnostic shouldn't include @lvalue in type of c3.
var c3 = C3()
// XXX TODO: This should not suggest `as!`
c3 as C4 // expected-error {{'C3' is not convertible to 'C4'}} 
// expected-note@-1{{did you mean to use 'as!' to force downcast?}} {{4-6=as!}}

// <rdar://problem/19495142> Various incorrect diagnostics for explicit type conversions
1 as Double as Float // expected-error{{cannot convert value of type 'Double' to type 'Float' in coercion}}
1 as Int as String // expected-error{{cannot convert value of type 'Int' to type 'String' in coercion}}
Double(1) as Double as String // expected-error{{cannot convert value of type 'Double' to type 'String' in coercion}}
["awd"] as [Int] // expected-error{{cannot convert value of type 'String' to expected element type 'Int'}}
([1, 2, 1.0], 1) as ([String], Int)
// expected-error@-1 2 {{cannot convert value of type 'Int' to expected element type 'String'}}
// expected-error@-2   {{cannot convert value of type 'Double' to expected element type 'String'}}
[[1]] as [[String]] // expected-error{{cannot convert value of type 'Int' to expected element type 'String'}}
(1, 1.0) as (Int, Int) // expected-error{{cannot convert value of type '(Int, Double)' to type '(Int, Int)' in coercion}}
(1.0, 1, "asd") as (String, Int, Float) // expected-error{{cannot convert value of type '(Double, Int, String)' to type '(String, Int, Float)' in coercion}}
(1, 1.0, "a", [1, 23]) as (Int, Double, String, [String])
// expected-error@-1 2 {{cannot convert value of type 'Int' to expected element type 'String'}}

_ = [1] as! [String] // OK
_ = [(1, (1, 1))] as! [(Int, (String, Int))] // OK

// <rdar://problem/19495253> Incorrect diagnostic for explicitly casting to the same type
_ = "hello" as! String // expected-warning{{forced cast of 'String' to same type has no effect}} {{13-24=}}

// <rdar://problem/19499340> QoI: Nimble as -> as! changes not covered by Fix-Its
func f(_ x : String) {}
f("what" as Any as String) // expected-error {{'Any' is not convertible to 'String'}} 
// expected-note@-1{{did you mean to use 'as!' to force downcast?}} {{17-19=as!}}
f(1 as String) // expected-error{{cannot convert value of type 'Int' to type 'String' in coercion}}

// <rdar://problem/19650402> Swift compiler segfaults while running the annotation tests
let s : AnyObject = C3()
s as C3 // expected-error{{'AnyObject' is not convertible to 'C3'}} 
// expected-note@-1{{did you mean to use 'as!' to force downcast?}} {{3-5=as!}}

// https://github.com/apple/swift/issues/48579

protocol P_48579 {}
do {
  func f1() -> Any {}
  func f2() {}
  @Sendable func f3() {}

  _ = f1 is P_48579 // expected-warning {{cast from '() -> Any' to unrelated type 'any P_48579' always fails}} // expected-note {{did you mean to call 'f1' with '()'?}}{{9-9=()}}
  _ = f1 as! P_48579 // expected-warning {{cast from '() -> Any' to unrelated type 'any P_48579' always fails}} // expected-note {{did you mean to call 'f1' with '()'?}}{{9-9=()}}
  _ = f1 as? P_48579 // expected-warning {{cast from '() -> Any' to unrelated type 'any P_48579' always fails}} // expected-note {{did you mean to call 'f1' with '()'}}{{9-9=()}}
  _ = f2 is P_48579 // expected-warning {{cast from '() -> ()' to unrelated type 'any P_48579' always fails}}
  _ = f2 as! P_48579 // expected-warning {{cast from '() -> ()' to unrelated type 'any P_48579' always fails}}
  _ = f2 as? P_48579 // expected-warning {{cast from '() -> ()' to unrelated type 'any P_48579' always fails}}

  _ = f1 as! AnyObject // expected-warning {{forced cast from '() -> Any' to 'AnyObject' always succeeds; did you mean to use 'as'?}}
  _ = f1 as? AnyObject // expected-warning {{conditional cast from '() -> Any' to 'AnyObject' always succeeds}}
  _ = f2 as! Any // expected-warning {{forced cast from '() -> ()' to 'Any' always succeeds; did you mean to use 'as'?}}
  _ = f2 as? Any // expected-warning {{conditional cast from '() -> ()' to 'Any' always succeeds}}


  func test1<T: P_48579, V: P_48579 & Sendable>(_: T.Type, _: V.Type) {
    _ = f1 is T // expected-warning {{cast from '() -> Any' to unrelated type 'T' always fails}} // expected-note {{did you mean to call 'f1' with '()'?}}{{11-11=()}}
    _ = f1 as! V // expected-warning {{cast from '() -> Any' to unrelated type 'V' always fails}} // expected-note {{did you mean to call 'f1' with '()'?}}{{11-11=()}}
    _ = f1 as? T // expected-warning {{cast from '() -> Any' to unrelated type 'T' always fails}} // expected-note {{did you mean to call 'f1' with '()'?}}{{11-11=()}}
    _ = f2 is T // expected-warning {{cast from '() -> ()' to unrelated type 'T' always fails}}
    _ = f2 as! V // expected-warning {{cast from '() -> ()' to unrelated type 'V' always fails}}
    _ = f2 as? T // expected-warning {{cast from '() -> ()' to unrelated type 'T' always fails}}
    _ = f3 is T // expected-warning {{cast from '@Sendable () -> ()' to unrelated type 'T' always fails}}
    _ = f3 as! V // expected-warning {{cast from '@Sendable () -> ()' to unrelated type 'V' always fails}}
    _ = f3 as? T // expected-warning {{cast from '@Sendable () -> ()' to unrelated type 'T' always fails}}
  }

  func test2<U, S: Sendable>(_: U.Type, _: S.Type) {
    _ = f1 is U  // Okay
    _ = f1 as! U // Okay
    _ = f1 as? U // Okay
    _ = f1 is U  // Okay
    _ = f2 as! U // Okay
    _ = f2 as? U // Okay

    _ = f2 is S   // expected-warning {{cast from '() -> ()' to unrelated type 'S' always fails}}
    _ = f2 as! S  // expected-warning {{cast from '() -> ()' to unrelated type 'S' always fails}}
    _ = f2 as? S  // expected-warning {{cast from '() -> ()' to unrelated type 'S' always fails}}
    _ = f3 is S   // Okay
    _ = f3 as! S  // Okay
    _ = f3 as? S  // Okay
  }
}

// https://github.com/apple/swift/issues/56297

let any: Any = 1
if let int = any as Int { // expected-error {{'Any' is not convertible to 'Int'}}
// expected-note@-1 {{did you mean to use 'as?' to conditionally downcast?}} {{18-20=as?}}
}

let _ = any as Int // expected-error {{'Any' is not convertible to 'Int'}}
// expected-note@-1 {{did you mean to use 'as!' to force downcast?}} {{13-15=as!}}
let _: Int = any as Int // expected-error {{'Any' is not convertible to 'Int'}}
// expected-note@-1 {{did you mean to use 'as!' to force downcast?}} {{18-20=as!}}
let _: Int? = any as Int // expected-error {{'Any' is not convertible to 'Int'}}
// expected-note@-1 {{did you mean to use 'as?' to conditionally downcast?}} {{19-21=as?}}

// https://github.com/apple/swift/issues/63926

do {
  func fn(_: Int) {} // expected-note {{found candidate with type '(Int) -> ()'}}
  // expected-note@-1 {{candidate '(Int) -> ()' has 1 parameter, but context '() -> Void' has 0}}
  func fn(_: Bool) {} // expected-note {{found candidate with type '(Bool) -> ()'}}
  // expected-note@-1 {{candidate '(Bool) -> ()' has 1 parameter, but context '() -> Void' has 0}}

  func fn_1(_: Bool) {} 

  let i = 0
  // Missing parameters.
  (fn as (Int, Int) -> Void)(i, i) // expected-error {{cannot convert value of type '(Int) -> ()' to type '(Int, Int) -> Void' in coercion}}
  (fn as (Bool, Bool) -> Void)(i, i) // expected-error {{cannot convert value of type '(Bool) -> ()' to type '(Bool, Bool) -> Void' in coercion}}
  // expected-error@-1 2{{type 'Int' cannot be used as a boolean; test for '!= 0' instead}}
  (fn as (Int, Bool) -> Void)(i, i) // expected-error {{cannot convert value of type '(Int) -> ()' to type '(Int, Bool) -> Void' in coercion}}
  // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}}
  (fn as (String) -> Void)(i) // expected-error {{no exact matches in reference to local function 'fn'}}
  // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'String'}}

  // Extraneous parameters.
  (fn as () -> Void)() // expected-error {{no exact matches in reference to local function 'fn'}}
  (fn_1 as () -> Void)() // expected-error {{cannot convert value of type '(Bool) -> ()' to type '() -> Void' in coercion}}
}

// Test generic parameter inference through casts
do {
  class A<T> {
  }

  class B<U> : A<U> {
  }

  func test(v: any B<Int> & Sendable) {
    _ = v as A // infers `Int` for `A.T`
  }
}