File: opaque_parameters.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 (133 lines) | stat: -rw-r--r-- 3,571 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
// RUN: %target-typecheck-verify-swift -disable-availability-checking

protocol P { }

protocol Q {
  associatedtype A: P & Equatable

  func f() -> A
  func takesA(_: A)
}

extension Int: P { }
extension String: P { }

// expected-note@+1{{requirement from conditional conformance of '[Double]' to 'Q'}}
extension Array: Q where Element: P, Element: Equatable {
  func f() -> Element {
    return first!
  }

  func takesA(_: Element) {}
}

extension Set: Q where Element: P, Element: Equatable {
  func f() -> Element {
    return first!
  }

  func takesA(_: Element) {}
}

// expected-note@+2{{where 'some Q' = 'Int'}}
// expected-note@+1{{in call to function 'takesQ'}}
func takesQ(_ q: some Q) -> Bool {
  // expected-error@+1 {{cannot convert value of type 'Int' to expected argument type '(some Q).A'}}
  q.takesA(1)

  return q.f() == q.f()
}

func testTakesQ(arrayOfInts: [Int], setOfStrings: Set<String>, i: Int) {
  _ = takesQ(arrayOfInts)
  _ = takesQ(setOfStrings)
  _ = takesQ(i) // expected-error{{global function 'takesQ' requires that 'Int' conform to 'Q'}}

  let f = takesQ // expected-error{{generic parameter 'some Q' could not be inferred}}
  let _: ([String]) -> Bool = takesQ
  let _: ([Double]) -> Bool = takesQ // expected-error{{global function 'takesQ' requires that 'Double' conform to 'P'}}
  _ = f
}

// expected-note@+1{{where 'some P' = '[Int]'}}
func takeMultiple<T>(_: T, _: some Q, _: some P) { }

func testTakeMultiple(
  arrayOfInts: [Int], setOfStrings: Set<String>, i: Int, d: Double
) {
  takeMultiple(d, arrayOfInts, i)
  takeMultiple(d, arrayOfInts, arrayOfInts) // expected-error{{global function 'takeMultiple' requires that '[Int]' conform to 'P'}}
}

// inout

func anyInOut(_: inout some P) { }

func testAnyInOut() {
  var i = 17
  anyInOut(&i)
}

// In structural positions.
func anyDictionary(_ dict: [some Hashable: some Any]) { }

func testAnyDictionary(numberNames: [Int: String]) {
  anyDictionary(numberNames)
}

// Combine with parameterized protocol types
protocol PrimaryCollection<Element>: Collection {}

extension Array: PrimaryCollection { }
extension Set: PrimaryCollection { }

func takePrimaryCollections(
  _ strings: some PrimaryCollection<String>,
  _ ints : some PrimaryCollection<Int>
) {
  for s in strings {
    let _: String = s
  }

  for i in ints {
    let _: Int = i
  }
}

func takeMatchedPrimaryCollections<T: Equatable>(
  _ first: some PrimaryCollection<T>, _ second: some PrimaryCollection<T>
) -> Bool {
  first.elementsEqual(second)
}

func testPrimaries(
  arrayOfInts: [Int], setOfStrings: Set<String>, setOfInts: Set<Int>
) {
  takePrimaryCollections(setOfStrings, setOfInts)
  takePrimaryCollections(setOfStrings, arrayOfInts)
  _ = takeMatchedPrimaryCollections(arrayOfInts, setOfInts)
  _ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without a type annotation}}
}


// Prohibit use of opaque parameters in consuming positions.
typealias FnType<T> = (T) -> Void

func consumingA(fn: (some P) -> Void) { } // expected-error{{'some' cannot appear in parameter position in parameter type '(some P) -> Void'}}
func consumingB(fn: FnType<some P>) { } // expected-error{{'some' cannot appear in parameter position in parameter type '(some P) -> Void'}}

// https://github.com/apple/swift/issues/61387
struct I61387 {
  subscript(s: some StringProtocol) -> String {
    fatalError()
  }
}

struct I61387_1 {
  subscript(s: some StringProtocol) -> String {
    get { fatalError() }
    set {
      fatalError()
    }
  }
}