forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 1
/
opaque_parameters.swift
104 lines (82 loc) · 2.77 KB
/
opaque_parameters.swift
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
// RUN: %target-typecheck-verify-swift -enable-experimental-opaque-parameters -enable-parametrized-protocol-types -disable-availability-checking
protocol P { }
protocol Q {
associatedtype A: P & Equatable
func f() -> 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!
}
}
extension Set: Q where Element: P, Element: Equatable {
func f() -> Element {
return first!
}
}
// expected-note@+2{{where 'some Q' = 'Int'}}
// expected-note@+1{{in call to function 'takesQ'}}
func takesQ(_ q: some Q) -> Bool {
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: Collection {
@_primaryAssociatedType associatedtype Element
}
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 more context}}
}