@@ -133,6 +133,16 @@ determined dynamically at runtime:
133133 func a (c : C) {
134134 c.method ()
135135 }
136+ - Calls through `class` methods on `class` types and the method referenced
137+ is not `final `
138+ ```swift
139+ class C {
140+ @inline (always)
141+ class func method () {... }
142+ }
143+ func a (c : C.Type ) {
144+ c.method ()
145+ }
136146 ```
137147
138148In such cases, the compiler cannot determine at a call site which function is
@@ -144,8 +154,8 @@ function references in the following:
144154
145155- Calls to free standing functions
146156- Calls to methods of `actor`, `struct`, `enum` type
147- - Calls to final methods of `class` type, and type (`static/ class`) methods of
148- `class` type
157+ - Calls to final methods, final `class` type methods of ` class` type, and
158+ `static` type methods of ` class` type
149159
150160Therefore, in cases where the value of the function at a usage site is
151161dynamically derived we don't emit an error even if the dynamic value of the
@@ -171,9 +181,10 @@ Listing the different scenarios that can occur for a function marked with
171181### Direct function references
172182
173183Calls to freestanding functions, methods of `enum`, `struct`, `actor` types,
174- final methods of `class` types, and type methods of `class` types don't
175- dynamically dispatch to different implementations. Calls to such methods can
176- always be inlined barring the recursion limitation (see later). (case 1 )
184+ final methods of `class` types, and `static` (but not `class`) type methods of
185+ `class` types don't dynamically dispatch to different implementations. Calls to
186+ such methods can always be inlined barring the recursion limitation (see later).
187+ (case 1 )
177188
178189```swift
179190struct S {
@@ -191,7 +202,10 @@ class C {
191202 final func finalMethod () {}
192203
193204 @inline (always)
194- class func method () {}
205+ static func method () {}
206+
207+ @inline (always)
208+ final class func finalTypeMethod ()
195209}
196210
197211class Sub : C {}
@@ -202,6 +216,8 @@ func f2() {
202216 let c2: Sub = ..
203217 c2.finalMethod () // can definitely be inlined
204218 C.method () // can definitely be inlined
219+ let c: C.Type = ...
220+ c.finalTypeMethod () // can definitely be inlined
205221}
206222
207223@inline (always)
@@ -215,28 +231,36 @@ func f3() {
215231
216232### Non final class methods
217233
218- Swift performs dynamic dispatch for non-final methods of classes based on the
219- dynamic receiver type of the class instance value at a use site. Inferring the
220- value of that dynamic computation at compile time is not possible in many cases
221- and the success of inlining cannot be ensured. We treat a non-final method
222- declaration with ` @inline(always) ` as an declaration site error because we
223- assume that the intention of the attribute is that the method will be inlined in
224- most cases and this cannot be guaranteed (case 3).
234+ Swift performs dynamic dispatch for non-final methods of classes and non final
235+ ` class ` methods of classes based on the dynamic receiver type of the class
236+ instance/class type value at a use site. Inferring the value of that dynamic
237+ computation at compile time is not possible in many cases and the success of
238+ inlining cannot be ensured. We treat a non-final method declaration with
239+ ` @inline(always) ` as an declaration site error because we assume that the
240+ intention of the attribute is that the method will be inlined in most cases and
241+ this cannot be guaranteed (case 3).
225242
226243``` swift
227244class C {
228245 @inline (always) // error: non-final method marked @inline(always)
229246 func method () {}
247+
248+ @inline (always) // error: non-final method marked @inline(always)
249+ class func class_method () {}
230250}
231251
232252class C2 : C {
233253 @inline (always) // error: non-final method marked @inline(always)
234254 override func method () {}
255+
256+ class func class_method () {}
235257}
236258
237- func f (c : C) {
259+ func f (c : C, c2 : C. Type ) {
238260 c.method () // dynamic type of c might be C or C2, could not ensure success
239261 // of inlining in general
262+ c2.class_method () // dynamic type of c2 might be C.self or C2.self, could not
263+ // ensure success of inlining in general
240264}
241265```
242266
@@ -357,13 +381,13 @@ to the client.
357381
358382` @inline(always) ` intention is to be able to guarantee that inlining will happen
359383for any caller inside or outside the defining module therefore it makes sense to
360- require the use of " @inlinable " attribute with them. This attribute could be
384+ require the use of an ` @inlinable ` attribute with them. This attribute could be
361385required to be explicitly stated. And for it to be an error when the attribute
362386is omitted.
363387
364388``` swift
365389@inline (always)
366- @inlinable // or @_alwaysEmitIntoClient
390+ @inlinable
367391public func caller () { ... }
368392
369393@inline (always) // error: a public function marked @inline(always) must be marked @inlinable
@@ -467,13 +491,13 @@ attribute in the future.
467491
468492``` swift
469493@inlinable
470- public caller () {
494+ public func caller () {
471495 if coldPath {
472496 callee ()
473497 }
474498}
475499
476- public otherCaller () {
500+ public func otherCaller () {
477501 if hotPath {
478502 callee ()
479503 }
0 commit comments