forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
attr_inlinable.swift
373 lines (307 loc) · 12.6 KB
/
attr_inlinable.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
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
// RUN: %target-typecheck-verify-swift -swift-version 5
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-testing
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-library-evolution
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-library-evolution -enable-testing
@inlinable struct TestInlinableStruct {}
// expected-error@-1 {{'@inlinable' attribute cannot be applied to this declaration}}
@inlinable @usableFromInline func redundantAttribute() {}
// expected-warning@-1 {{'@usableFromInline' attribute has no effect on '@inlinable' global function 'redundantAttribute()'}} {{12-30=}}
private func privateFunction() {}
// expected-note@-1 2{{global function 'privateFunction()' is not '@usableFromInline' or public}}
fileprivate func fileprivateFunction() {}
// expected-note@-1{{global function 'fileprivateFunction()' is not '@usableFromInline' or public}}
func internalFunction() {}
// expected-note@-1 2{{global function 'internalFunction()' is not '@usableFromInline' or public}}
@usableFromInline func versionedFunction() {}
public func publicFunction() {}
private struct PrivateStruct {}
// expected-note@-1 5{{struct 'PrivateStruct' is not '@usableFromInline' or public}}
// expected-note@-2 2{{initializer 'init()' is not '@usableFromInline' or public}}
struct InternalStruct {}
// expected-note@-1 3{{struct 'InternalStruct' is not '@usableFromInline' or public}}
// expected-note@-2 {{initializer 'init()' is not '@usableFromInline' or public}}
@usableFromInline struct VersionedStruct {
@usableFromInline init() {}
}
public struct PublicStruct {
public init() {}
@inlinable public var storedProperty: Int
// expected-error@-1 {{'@inlinable' attribute cannot be applied to stored properties}}
@inlinable public lazy var lazyProperty: Int = 0
// expected-error@-1 {{'@inlinable' attribute cannot be applied to stored properties}}
}
public struct Struct {
@_transparent
public func publicTransparentMethod() {
struct Nested {}
// expected-error@-1 {{type 'Nested' cannot be nested inside a '@_transparent' function}}
publicFunction()
// OK
versionedFunction()
// OK
internalFunction()
// expected-error@-1 {{global function 'internalFunction()' is internal and cannot be referenced from a '@_transparent' function}}
fileprivateFunction()
// expected-error@-1 {{global function 'fileprivateFunction()' is fileprivate and cannot be referenced from a '@_transparent' function}}
privateFunction()
// expected-error@-1 {{global function 'privateFunction()' is private and cannot be referenced from a '@_transparent' function}}
}
@inlinable
public func publicInlinableMethod() {
struct Nested {}
// expected-error@-1 {{type 'Nested' cannot be nested inside an '@inlinable' function}}
let _: PublicStruct
let _: VersionedStruct
let _: InternalStruct
// expected-error@-1 {{struct 'InternalStruct' is internal and cannot be referenced from an '@inlinable' function}}
let _: PrivateStruct
// expected-error@-1 {{struct 'PrivateStruct' is private and cannot be referenced from an '@inlinable' function}}
let _ = PublicStruct.self
let _ = VersionedStruct.self
let _ = InternalStruct.self
// expected-error@-1 {{struct 'InternalStruct' is internal and cannot be referenced from an '@inlinable' function}}
let _ = PrivateStruct.self
// expected-error@-1 {{struct 'PrivateStruct' is private and cannot be referenced from an '@inlinable' function}}
let _ = PublicStruct()
let _ = VersionedStruct()
let _ = InternalStruct()
// expected-error@-1 {{struct 'InternalStruct' is internal and cannot be referenced from an '@inlinable' function}}
// expected-error@-2 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
let _ = PrivateStruct()
// expected-error@-1 {{struct 'PrivateStruct' is private and cannot be referenced from an '@inlinable' function}}
// expected-error@-2 {{initializer 'init()' is private and cannot be referenced from an '@inlinable' function}}
}
private func privateMethod() {}
// expected-note@-1 {{instance method 'privateMethod()' is not '@usableFromInline' or public}}
@_transparent
@usableFromInline
func versionedTransparentMethod() {
struct Nested {}
// expected-error@-1 {{type 'Nested' cannot be nested inside a '@_transparent' function}}
privateMethod()
// expected-error@-1 {{instance method 'privateMethod()' is private and cannot be referenced from a '@_transparent' function}}
}
@inlinable
func internalInlinableMethod() {
struct Nested {}
// expected-error@-1 {{type 'Nested' cannot be nested inside an '@inlinable' function}}
}
@_transparent
func internalTransparentMethod() {
struct Nested {}
// OK
}
@inlinable
private func privateInlinableMethod() {
// expected-error@-2 {{'@inlinable' attribute can only be applied to public declarations, but 'privateInlinableMethod' is private}}
struct Nested {}
// expected-error@-1 {{type 'Nested' cannot be nested inside an '@inlinable' function}}
}
@inline(__always)
func internalInlineAlwaysMethod() {
struct Nested {}
// OK
}
}
// Make sure protocol extension members can reference protocol requirements
// (which do not inherit the @usableFromInline attribute).
@usableFromInline
protocol VersionedProtocol {
associatedtype T
func requirement() -> T
}
extension VersionedProtocol {
func internalMethod() {}
// expected-note@-1 {{instance method 'internalMethod()' is not '@usableFromInline' or public}}
@inlinable
func versionedMethod() -> T {
internalMethod()
// expected-error@-1 {{instance method 'internalMethod()' is internal and cannot be referenced from an '@inlinable' function}}
return requirement()
}
}
enum InternalEnum {
// expected-note@-1 2{{enum 'InternalEnum' is not '@usableFromInline' or public}}
// expected-note@-2 {{type declared here}}
case apple
// expected-note@-1 {{enum case 'apple' is not '@usableFromInline' or public}}
case orange
// expected-note@-1 {{enum case 'orange' is not '@usableFromInline' or public}}
}
@inlinable public func usesInternalEnum() {
_ = InternalEnum.apple
// expected-error@-1 {{enum 'InternalEnum' is internal and cannot be referenced from an '@inlinable' function}}
// expected-error@-2 {{enum case 'apple' is internal and cannot be referenced from an '@inlinable' function}}
let _: InternalEnum = .orange
// expected-error@-1 {{enum 'InternalEnum' is internal and cannot be referenced from an '@inlinable' function}}
// expected-error@-2 {{enum case 'orange' is internal and cannot be referenced from an '@inlinable' function}}
}
@usableFromInline enum VersionedEnum {
case apple
case orange
case pear(InternalEnum)
// expected-error@-1 {{type of enum case in '@usableFromInline' enum must be '@usableFromInline' or public}}
case persimmon(String)
}
@inlinable public func usesVersionedEnum() {
_ = VersionedEnum.apple
let _: VersionedEnum = .orange
_ = VersionedEnum.persimmon
}
// Inherited initializers - <rdar://problem/34398148>
@usableFromInline
@_fixed_layout
class Base {
@usableFromInline
init(x: Int) {}
}
@usableFromInline
@_fixed_layout
class Middle : Base {}
@usableFromInline
@_fixed_layout
class Derived : Middle {
@inlinable
init(y: Int) {
super.init(x: y)
}
}
// More inherited initializers
@_fixed_layout
public class Base2 {
@inlinable
public init(x: Int) {}
}
@_fixed_layout
@usableFromInline
class Middle2 : Base2 {}
@_fixed_layout
@usableFromInline
class Derived2 : Middle2 {
@inlinable
init(y: Int) {
super.init(x: y)
}
}
// https://github.com/apple/swift/issues/53331
// Even more inherited initializers.
@_fixed_layout
public class Base3 {}
// expected-note@-1 {{initializer 'init()' is not '@usableFromInline' or public}}
@_fixed_layout
public class Derived3 : Base3 {
@inlinable
public init(_: Int) {}
// expected-error@-1 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
// expected-note@-2 {{call to unavailable initializer 'init()' from superclass 'Base3' occurs implicitly at the end of this initializer}}
}
@_fixed_layout
public class Base4 {}
@_fixed_layout
@usableFromInline
class Middle4 : Base4 {}
// expected-note@-1 {{initializer 'init()' is not '@usableFromInline' or public}}
@_fixed_layout
@usableFromInline
class Derived4 : Middle4 {
@inlinable
public init(_: Int) {}
// expected-error@-1 {{initializer 'init()' is internal and cannot be referenced from an '@inlinable' function}}
// expected-note@-2 {{call to unavailable initializer 'init()' from superclass 'Middle4' occurs implicitly at the end of this initializer}}
}
// Stored property initializer expressions.
//
// Note the behavior here does not depend on the state of the -enable-library-evolution
// flag; the test runs with both the flag on and off. Only the explicit
// presence of a '@_fixed_layout' attribute determines the behavior here.
let internalGlobal = 0
// expected-note@-1 {{let 'internalGlobal' is not '@usableFromInline' or public}}
public let publicGlobal = 0
struct InternalStructWithInit {
var x = internalGlobal // OK
var y = publicGlobal // OK
}
public struct PublicResilientStructWithInit {
var x = internalGlobal // OK
var y = publicGlobal // OK
}
private func privateIntReturningFunc() -> Int { return 0 }
internal func internalIntReturningFunc() -> Int { return 0 }
@frozen
public struct PublicFixedStructWithInit {
var x = internalGlobal // expected-error {{let 'internalGlobal' is internal and cannot be referenced from a property initializer in a '@frozen' type}}
var y = publicGlobal // OK
// Static property initializers are not inlinable contexts.
static var z = privateIntReturningFunc() // OK
static var a = internalIntReturningFunc() // OK
// Test the same with a multi-statement closure, which introduces a
// new DeclContext.
static var zz: Int = {
let x = privateIntReturningFunc()
return x
}()
static var aa: Int = {
let x = internalIntReturningFunc()
return x
}()
}
public struct KeypathStruct {
var x: Int
// expected-note@-1 {{property 'x' is not '@usableFromInline' or public}}
@inlinable public func usesKeypath() {
_ = \KeypathStruct.x
// expected-error@-1 {{property 'x' is internal and cannot be referenced from an '@inlinable' function}}
}
}
public struct HasInternalSetProperty {
public internal(set) var x: Int // expected-note {{setter for property 'x' is not '@usableFromInline' or public}}
@inlinable public mutating func setsX() {
x = 10 // expected-error {{setter for property 'x' is internal and cannot be referenced from an '@inlinable' function}}
}
}
@usableFromInline protocol P {
typealias T = Int
}
extension P {
@inlinable func f() {
_ = T.self // ok, typealias inherits @usableFromInline from P
}
}
// rdar://problem/60605117
public struct PrivateInlinableCrash {
@inlinable // expected-error {{'@inlinable' attribute can only be applied to public declarations, but 'formatYesNo' is private}}
private func formatYesNo(_ value: Bool) -> String {
value ? "YES" : "NO"
}
}
// https://github.com/apple/swift/issues/54842
@inlinable public func inlinableOuterFunction() {
func innerFunction1(x: () = privateFunction()) {}
// expected-error@-1 {{global function 'privateFunction()' is private and cannot be referenced from a default argument value}}
func innerFunction2(x: () = internalFunction()) {}
// expected-error@-1 {{global function 'internalFunction()' is internal and cannot be referenced from a default argument value}}
func innerFunction3(x: () = versionedFunction()) {}
func innerFunction4(x: () = publicFunction()) {}
}
// This is OK -- lazy property initializers are emitted inside the getter,
// which is never @inlinable.
@frozen public struct LazyField {
public lazy var y: () = privateFunction()
@inlinable private lazy var z: () = privateFunction()
// expected-error@-1 {{'@inlinable' attribute cannot be applied to stored properties}}
}
@inlinable public func nestedBraceStmtTest() {
if true {
let _: PrivateStruct = PrivateStruct()
// expected-error@-1 2{{struct 'PrivateStruct' is private and cannot be referenced from an '@inlinable' function}}
// expected-error@-2 {{initializer 'init()' is private and cannot be referenced from an '@inlinable' function}}
}
}
// Just make sure we don't crash.
private func deferBodyTestCall() {} // expected-note {{global function 'deferBodyTestCall()' is not '@usableFromInline' or public}}
@inlinable public func deferBodyTest() {
defer {
deferBodyTestCall() // expected-error {{global function 'deferBodyTestCall()' is private and cannot be referenced from an '@inlinable' function}}
}
_ = ()
}