mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This attribute allows to define a pre-specialized entry point of a
generic function in a library.
The following definition provides a pre-specialized entry point for
`genericFunc(_:)` for the parameter type `Int` that clients of the
library can call.
```
@_specialize(exported: true, where T == Int)
public func genericFunc<T>(_ t: T) { ... }
```
Pre-specializations of internal `@inlinable` functions are allowed.
```
@usableFromInline
internal struct GenericThing<T> {
@_specialize(exported: true, where T == Int)
@inlinable
internal func genericMethod(_ t: T) {
}
}
```
There is syntax to pre-specialize a method from a different module.
```
import ModuleDefiningGenericFunc
@_specialize(exported: true, target: genericFunc(_:), where T == Double)
func prespecialize_genericFunc(_ t: T) { fatalError("dont call") }
```
Specially marked extensions allow for pre-specialization of internal
methods accross module boundries (respecting `@inlinable` and
`@usableFromInline`).
```
import ModuleDefiningGenericThing
public struct Something {}
@_specializeExtension
extension GenericThing {
@_specialize(exported: true, target: genericMethod(_:), where T == Something)
func prespecialize_genericMethod(_ t: T) { fatalError("dont call") }
}
```
rdar://64993425
113 lines
1.9 KiB
Swift
113 lines
1.9 KiB
Swift
@usableFromInline
|
|
struct ResilientInternalBoxedThing<T> {
|
|
@usableFromInline
|
|
var t: T
|
|
|
|
@usableFromInline
|
|
init(_ t: T) {
|
|
self.t = t
|
|
}
|
|
}
|
|
|
|
@usableFromInline
|
|
@frozen
|
|
struct InternalThing<T> {
|
|
@usableFromInline
|
|
var t: T
|
|
|
|
@usableFromInline
|
|
init(_ t: T) {
|
|
self.t = t
|
|
}
|
|
|
|
@_specialize(exported: true, where T == Int)
|
|
@_specialize(exported: true, where T == Bool)
|
|
@_specialize(exported: true, where T == ResilientInternalBoxedThing<Int>)
|
|
@inlinable
|
|
func compute() -> T {
|
|
return t
|
|
}
|
|
|
|
@inlinable
|
|
var computedX : T {
|
|
@_specialize(exported: true, where T == Int)
|
|
get {
|
|
return t
|
|
}
|
|
@_specialize(exported: true, where T == Int)
|
|
set {
|
|
t = newValue
|
|
}
|
|
}
|
|
|
|
@inlinable
|
|
subscript(_ i: Int) -> T {
|
|
@_specialize(exported: true, where T == Int)
|
|
get {
|
|
return t
|
|
}
|
|
@_specialize(exported: true, where T == Int)
|
|
set {
|
|
t = newValue
|
|
}
|
|
}
|
|
}
|
|
|
|
@usableFromInline
|
|
class InternalRef<T> {
|
|
@usableFromInline
|
|
var t: T
|
|
|
|
@usableFromInline
|
|
init(_ t: T) {
|
|
self.t = t
|
|
}
|
|
|
|
@_specialize(exported: true, where T == Int)
|
|
@_specialize(exported: true, where T == Bool)
|
|
@_specialize(exported: true, where T == ResilientInternalBoxedThing<Int>)
|
|
@inlinable
|
|
final func compute() -> T {
|
|
return t
|
|
}
|
|
|
|
@inlinable
|
|
final var computedX : T {
|
|
@_specialize(exported: true, where T == Int)
|
|
get {
|
|
return t
|
|
}
|
|
@_specialize(exported: true, where T == Int)
|
|
set {
|
|
t = newValue
|
|
}
|
|
}
|
|
|
|
@inlinable
|
|
final subscript(_ i: Int) -> T {
|
|
@_specialize(exported: true, where T == Int)
|
|
get {
|
|
return t
|
|
}
|
|
@_specialize(exported: true, where T == Int)
|
|
set {
|
|
t = newValue
|
|
}
|
|
}
|
|
}
|
|
|
|
@inline(never)
|
|
@inlinable
|
|
public func testSpecialization<T>(_ t: T) {
|
|
print(InternalThing(ResilientInternalBoxedThing(t)).compute())
|
|
|
|
print(InternalThing(t).compute())
|
|
|
|
var i = InternalThing(t)
|
|
i.computedX = t
|
|
print(i.computedX)
|
|
|
|
i[1] = t
|
|
print(i[2])
|
|
}
|