-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathavailability_parameterized_existential.swift
166 lines (132 loc) · 8.3 KB
/
availability_parameterized_existential.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
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
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module
// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -typecheck %s 2>&1 | %FileCheck %s '--implicit-check-not=<unknown>:0'
// Make sure we do not emit availability errors or warnings when -disable-availability-checking is passed
// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -typecheck -disable-objc-attr-requires-foundation-module -disable-availability-checking %s -diagnostic-style llvm 2>&1 | %FileCheck %s '--implicit-check-not=error:'
// REQUIRES: OS=macosx
func hedge() {
struct Value {}
// We rely on not allowing nesting of extensions, so test to make sure
// this emits an error.
// CHECK:error: declaration is only valid at file scope
extension Value { } // expected-error {{declaration is only valid at file scope}}
}
protocol P<T> {
associatedtype T
}
struct Wrapper<T> {}
func identity<T>(_ x: any P<T>) -> any P<T> { return x } // OK
func unwrapUnwrap<T>(_ x: (any P<T>)???) -> (any P<T>)? { return x!! } // OK
func erase<T>(_ x: any P<T>) -> Any { return x }
func nonerasingFunction<T>(_ f: @escaping (any P<T>) -> ()) -> Any { return 0 }
func eraseFunction<T>(_ f: @escaping (any P<T>) -> ()) -> Any { return f } // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note@-1 {{add @available attribute to enclosing global function}}
// expected-note@-2 {{add 'if #available' version check}}
// These are okay because we can convert between existentials without metadata.
func eraseFunctionCovariant<T>(_ f: @escaping () -> any P<T>) -> (() -> Any) {
return f
}
func eraseFunctionContravariant<T>(_ f: @escaping (Any) -> ()) -> ((any P<T>) -> Any) {
return f
}
// We cannot convert from an optional existential to an existential without
// metadata.
func eraseFunctionCovariantOptional<T>(_ f: @escaping () -> (any P<T>)?) -> (() -> Any) {
return f // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note@-2 {{add @available attribute to enclosing global function}}
// expected-note@-2 {{add 'if #available' version check}}
}
func eraseFunctionContravariantOptional<T>(_ f: @escaping (Any) -> ()) -> (((any P<T>)?) -> Any) {
return f // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note@-2 {{add @available attribute to enclosing global function}}
// expected-note@-2 {{add 'if #available' version check}}
}
func eraseOptional<T>(_ x: (any P<T>)?) -> Any { return x }
// expected-note@-1 {{add @available attribute to enclosing global function}}
// expected-error@-2 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-3 {{add 'if #available' version check}}
// expected-warning@-4 {{expression implicitly coerced from '(any P<T>)?' to 'Any'}}
// expected-note@-5 {{provide a default value to avoid this warning}}
// expected-note@-6 {{force-unwrap the value to avoid this warning}}
// expected-note@-7 {{explicitly cast to 'Any' with 'as Any' to silence this warning}}
func eraseOptional2<T>(_ x: (any P<T>)?) -> Any { return x as Any }
// expected-note@-1 {{add @available attribute to enclosing global function}}
// expected-error@-2 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-3 {{add 'if #available' version check}}
func tupleOut<T>() -> (any P<T>, Int) { return tupleOut() }
func tupleIn<T>(_ xs: (any P<T>, Int)) -> Int { return tupleIn(xs) }
func wrap<T>(_ x: any P<T>) -> Wrapper<any P<T>> { return wrap(x) } // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note@-1 {{add @available attribute to enclosing global function}}
func optionalWrap<T>(_ x: any P<T>) -> Wrapper<(any P<T>)?> { return optionalWrap(x) } // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note@-1 {{add @available attribute to enclosing global function}}
struct UnavailableWitness: P { // expected-note {{add @available attribute to enclosing struct}}
typealias T = any P<String> // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note@-1 {{add @available attribute to enclosing type alias}}
}
struct UnavailableOptionalWitness: P { // expected-note {{add @available attribute to enclosing struct}}
typealias T = (any P<String>)? // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note@-1 {{add @available attribute to enclosing type alias}}
}
struct UnavailableWrappedWitness: P { // expected-note 2 {{add @available attribute to enclosing struct}}
typealias T = Wrapper<any P<String>> // expected-error 2 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-1 2 {{add @available attribute to enclosing type alias}}
}
struct ParameterizedMembers { // expected-note {{add @available attribute to enclosing struct}}
var ok: any P<String>
var okOptional: (any P<String>)?
var broken: Wrapper<(any P<String>)?> // expected-error {{runtime support for parameterized protocol types is only available in}}
}
func casts() { // expected-note 4 {{add @available attribute to enclosing global function}}
struct Value: P { typealias T = String }
let _ = Value() as any P<String> // OK
let _ = Value() as! any P<String>
// expected-warning@-1 {{forced cast from 'Value' to 'any P<String>' always succeeds; did you mean to use 'as'?}}
// expected-error@-2 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-3 {{add 'if #available' version check}}
let _ = Value() is any P<String>
// expected-warning@-1 {{'is' test is always true}}
// expected-error@-2 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-3 {{add 'if #available' version check}}
let _ = Value() is (any P<String>)???
// expected-warning@-1 {{'is' test is always true}}
// expected-error@-2 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-3 {{add 'if #available' version check}}
let _ = Value() as! (any P<String>, Int)
// expected-warning@-1 {{cast from 'Value' to unrelated type '(any P<String>, Int)' always fails}}
// expected-error@-2 1 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-3 1 {{add 'if #available' version check}}
}
// FIXME: It's a little aggressive to also ban metatypes.
func metatypes<T>(_ x: T.Type) { // expected-note 2 {{add @available attribute to enclosing global function}}
metatypes((any P<T>).self)
// expected-error@-1 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-2 {{add 'if #available' version check}}
metatypes((any P<T>.Type).self)
// expected-error@-1 {{runtime support for parameterized protocol types is only available in}}
// expected-note@-2 {{add 'if #available' version check}}
}
func tupleConversion1<T>(_ tuple: (any P<T>, Int)) {
let converted: (any P<T>, Int?) = tuple
_ = converted
}
func tupleConversion2<T>(_ tuple: (any P<T>, Int)) {
let converted: (Any, Int?) = tuple
_ = converted
}
func tupleConversion3<T>(_ tuple: ((any P<T>)?, Int)) {
// expected-note @-1 {{add @available attribute to enclosing global function}}
let converted: (Any, Int?) = tuple // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note @-1 {{add 'if #available' version check}}
// expected-warning @-3 {{expression implicitly coerced from '(any P<T>)?' to 'Any'}}
// expected-note @-4 {{explicitly cast to 'Any'}}
// expected-note @-5 {{force-unwrap the value}}
// expected-note @-6 {{provide a default value}}
_ = converted
}
func tupleCovariantConversion1<T>(fn: @escaping () -> (any P<T>, Int)) -> (() -> (Any, Int)) {
return fn
}
func tupleCovariantConversion2<T>(fn: @escaping () -> ((any P<T>)?, Int)) -> (() -> (Any, Int)) {
// expected-note @-1 {{add @available attribute to enclosing global function}}
return fn // expected-error {{runtime support for parameterized protocol types is only available in}}
// expected-note @-1 {{add 'if #available' version check}}
}