Files
swift-mirror/test/IRGen/Inputs/pre_specialize_module.swift
Arnold Schwaighofer b994bf3191 Add support for _specialize(exported: true, ...)
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
2020-10-12 09:19:29 -07:00

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])
}