File: operator.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 (331 lines) | stat: -rw-r--r-- 8,692 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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
// RUN: %target-typecheck-verify-swift

// https://github.com/apple/swift/issues/43735
// Test constraint simplification of chains of binary operators.
do {
  let a: String? = "a"
  let b: String? = "b"
  let c: String? = "c"
  let _: String? = a! + b! + c!

  let x: Double = 1
  _ = x + x + x

  // https://github.com/apple/swift/issues/46071
  let y1: Double? = 1
  _ = y1! + y1! + y1!

  // https://github.com/apple/swift/issues/45241
  let y2: [String: Double] = ["pizza": 10.99, "ice cream": 4.99, "salad": 7.99]
  _ = y2["pizza"]!
  _ = y2["pizza"]! + y2["salad"]!
  _ = y2["pizza"]! + y2["salad"]! + y2["ice cream"]!
}

// Use operators defined within a type.
struct S0 {
  static func +(lhs: S0, rhs: S0) -> S0 { return lhs }
}

func useS0(lhs: S0, rhs: S0) { 
  _ = lhs + rhs
}

// Use operators defined within a generic type.
struct S0b<T> {
  static func + <U>(lhs: S0b<T>, rhs: U) -> S0b<U> { return S0b<U>() }
}

func useS0b(s1i: S0b<Int>, s: String) {
  var s1s = s1i + s
  s1s = S0b<String>()
  _ = s1s
}

// Use operators defined within a protocol extension.
infix operator %%%
infix operator %%%%

protocol P1 {
  static func %%%(lhs: Self, rhs: Self) -> Bool
}

extension P1 {
  static func %%%%(lhs: Self, rhs: Self) -> Bool {
    return !(lhs %%% rhs)
  }
}

func useP1Directly<T : P1>(lhs: T, rhs: T) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

struct S1 : P1 {
  static func %%%(lhs: S1, rhs: S1) -> Bool { return false }
}

func useP1Model(lhs: S1, rhs: S1) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

struct S1b<T> : P1 {
  static func %%%(lhs: S1b<T>, rhs: S1b<T>) -> Bool { return false }
}

func useP1ModelB(lhs: S1b<Int>, rhs: S1b<Int>) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

func useP1ModelBGeneric<T>(lhs: S1b<T>, rhs: S1b<T>) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

// Use operators defined within a protocol extension to satisfy a requirement.
protocol P2 {
  static func %%%(lhs: Self, rhs: Self) -> Bool
  static func %%%%(lhs: Self, rhs: Self) -> Bool
}

extension P2 {
  static func %%%%(lhs: Self, rhs: Self) -> Bool {
    return !(lhs %%% rhs)
  }
}

func useP2Directly<T : P2>(lhs: T, rhs: T) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

struct S2 : P2 {
  static func %%%(lhs: S2, rhs: S2) -> Bool { return false }
}

func useP2Model(lhs: S2, rhs: S2) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

struct S2b<T> : P2 {
  static func %%%(lhs: S2b<T>, rhs: S2b<T>) -> Bool { return false }
}

func useP2Model2(lhs: S2b<Int>, rhs: S2b<Int>) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

func useP2Model2Generic<T>(lhs: S2b<T>, rhs: S2b<T>) {
  _ = lhs %%% rhs
  _ = lhs %%%% rhs
}

// Using an extension of one protocol to satisfy another conformance.
protocol P3 { }

extension P3 {
  static func ==(lhs: Self, rhs: Self) -> Bool {
    return true
  }  
}

struct S3 : P3, Equatable { }

// rdar://problem/30220565
func shrinkTooFar(_ : Double, closure : ()->()) {}
func testShrinkTooFar() {
  shrinkTooFar(0*0*0) {}
}

// rdar://problem/33759839

enum E_33759839 {
    case foo
    case bar(String)
}

let foo_33759839 = ["a", "b", "c"]
let bar_33759839 = ["A", "B", "C"]

let _: [E_33759839] = foo_33759839.map { .bar($0) } +
                      bar_33759839.map { .bar($0) } +
                      [E_33759839.foo] // Ok

// rdar://problem/28688585

class B_28688585 {
  var value: Int

  init(value: Int) {
    self.value = value
  }

  func add(_ other: B_28688585) -> B_28688585 {
    return B_28688585(value: value + other.value)
  }
}

class D_28688585 : B_28688585 {
}

func + (lhs: B_28688585, rhs: B_28688585) -> B_28688585 {
  return lhs.add(rhs)
}

let var_28688585 = D_28688585(value: 1)
_ = var_28688585 + var_28688585 + var_28688585 // Ok

// rdar://problem/35740653 - Fix `LinkedExprAnalyzer` greedy operator linking

struct S_35740653 {
  var v: Double = 42

  static func value(_ value: Double) -> S_35740653 {
    return S_35740653(v: value)
  }

  static func / (lhs: S_35740653, rhs: S_35740653) -> Double {
     return lhs.v / rhs.v
  }
}

func rdar35740653(val: S_35740653) {
  let _ = 0...Int(val / .value(1.0 / 42.0)) // Ok
}

protocol P_37290898 {}
struct S_37290898: P_37290898 {}

func rdar37290898(_ arr: inout [P_37290898], _ element: S_37290898?) {
  arr += [element].compactMap { $0 } // Ok
}

// https://github.com/apple/swift/issues/50753
infix operator ??=
func ??= <T>(lhs: inout T?, rhs: T?) {}
var c: Int = 0 // expected-note {{change variable type to 'Int?' if it doesn't need to be declared as 'Int'}}
c ??= 5 // expected-error{{inout argument could be set to a value with a type other than 'Int'; use a value declared as type 'Int?' instead}}

func rdar46459603() {
  enum E {
  case foo(value: String)
  }

  let e = E.foo(value: "String")
  var arr = ["key": e]

  _ = arr.values == [e]
  // expected-error@-1 {{referencing operator function '==' on 'Equatable' requires that 'Dictionary<String, E>.Values' conform to 'Equatable'}}
  // expected-error@-2 {{cannot convert value of type '[E]' to expected argument type 'Dictionary<String, E>.Values'}}

  _ = [arr.values] == [[e]]
  // expected-error@-1 {{referencing operator function '==' on 'Array' requires that 'E' conform to 'Equatable'}} expected-note@-1 {{binary operator '==' cannot be synthesized for enums with associated values}}
  // expected-error@-2 {{cannot convert value of type 'Dictionary<String, E>.Values' to expected element type '[E]'}}
}

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

infix operator ^^^
func ^^^ (lhs: String, rhs: String) {}

// FIXME: Operator lookup does not reach local types so this must be a
// top-level struct (https://github.com/apple/swift/issues/51378).
struct S_53233 {
  static func ^^^ (lhs: S_53233, rhs: S_53233) {}
}
do {
  let s = S_53233()
  (^^^)(s, s)
  _ = (==)(0, 0)
}

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

precedencegroup PowerPrecedence {
  lowerThan: BitwiseShiftPrecedence
  higherThan: AdditionPrecedence
  associativity: right
}
infix operator ^^ : PowerPrecedence

extension Int {
  static func ^^ (lhs: Int, rhs: Int) -> Int {
    var result = 1
    for _ in 1...rhs { result *= lhs }
    return result
  }
}

_ = 1 ^^ 2 ^^ 3 * 4 // expected-error {{adjacent operators are in unordered precedence groups 'PowerPrecedence' and 'MultiplicationPrecedence'}}

// rdar://problem/60185506 - Ambiguity with Float comparison
func rdar_60185506() {
  struct X {
    var foo: Float
  }

  func test(x: X?) {
    let _ = (x?.foo ?? 0) <= 0.5 // Ok
  }
}

// rdar://problem/60727310
func rdar60727310() {
  func myAssertion<T>(_ a: T, _ op: ((T,T)->Bool), _ b: T) {}
  var e: Error? = nil
  myAssertion(e, ==, nil) // expected-error {{binary operator '==' cannot be applied to two '(any Error)?' operands}}
}

// https://github.com/apple/swift/issues/54877
// FIXME: Bad diagnostic.
func f_54877(_ e: Error) {
  func foo<T>(_ a: T, _ op: ((T, T) -> Bool)) {}
  foo(e, ==) // expected-error {{type of expression is ambiguous without a type annotation}}
}

// rdar://problem/62054241 - Swift compiler crashes when passing < as the sort function in sorted(by:) and the type of the array is not comparable
func rdar_62054241() {
  struct Foo {
    let a: Int
  }

  func test(_ arr: [Foo]) -> [Foo] {
    return arr.sorted(by: <) // expected-error {{no exact matches in reference to operator function '<'}}
    // expected-note@-1 {{found candidate with type '(Foo, Foo) -> Bool'}}
  }
}

// https://github.com/apple/swift/issues/53800
// Operator returning IUO doesn't implicitly unwrap

postfix operator ^^^
postfix func ^^^ (lhs: Int) -> Int! { 0 }

let x: Int = 1^^^

// https://github.com/apple/swift/issues/44672 - DiagnosticsQoI
do {
  enum TestEnum: Int {
    case First, Second
  }

  let number = 1
  let test = true || number == .First.rawValue // expected-error {{type 'Int' has no member 'First'}}
}

// https://github.com/apple/swift/issues/60954
enum I60954 {
  // expected-error@+1{{operator implementation without matching operator declaration}}
  func ?= (pattern: I60954?, version: Self) { // expected-error{{operator '?=' declared in type 'I60954' must be 'static'}}
    // expected-error@+2{{operator is not a known binary operator}}
    // expected-error@+1{{initializer 'init(_:)' requires that 'I60954' conform to 'StringProtocol'}}
    pattern ?= .init(version) // expected-error{{value of optional type 'I60954?' must be unwrapped to a value of type 'I60954'}}
    // expected-note@-1{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
    // expected-note@-2{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
  }
  init?<S>(_ string: S) where S: StringProtocol {} // expected-note{{where 'S' = 'I60954'}}
}