-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathproperty_wrappers.swift
97 lines (82 loc) · 3.38 KB
/
property_wrappers.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
// RUN: %target-swift-frontend -emit-sil -verify %s %S/Inputs/nontrivial_loadable_type.swift
// REQUIRES: asserts
// Test property wrapper differentiation coverage for a variety of property
// types: trivial, non-trivial loadable, and address-only.
import DifferentiationUnittest
// MARK: Property wrappers
@propertyWrapper
struct SimpleWrapper<Value> {
var wrappedValue: Value // stored property
}
@propertyWrapper
struct Wrapper<Value> {
private var value: Value
var wrappedValue: Value { // computed property
get { value }
set { value = newValue }
}
init(wrappedValue: Value) {
self.value = wrappedValue
}
}
// `DifferentiableWrapper` conditionally conforms to `Differentiable`.
@propertyWrapper
struct DifferentiableWrapper<Value> {
private var value: Value
var wrappedValue: Value { // computed property
get { value }
set { value = newValue }
}
init(wrappedValue: Value) {
self.value = wrappedValue
}
}
extension DifferentiableWrapper: Differentiable where Value: Differentiable {}
// MARK: Types with wrapped properties
struct Struct: Differentiable {
@Wrapper @SimpleWrapper var trivial: Float = 10
@Wrapper @SimpleWrapper var tracked: Tracked<Float> = 20
@Wrapper @SimpleWrapper var nontrivial: NontrivialLoadable<Float> = 30
// Tests SR-12800: semantic member accessors should have empty linear map structs.
@DifferentiableWrapper var differentiableWrapped: Float = 40
static func testGetters() {
let _: @differentiable(reverse) (Self) -> Float = { $0.trivial }
let _: @differentiable(reverse) (Self) -> Tracked<Float> = { $0.tracked }
let _: @differentiable(reverse) (Self) -> NontrivialLoadable<Float> = { $0.nontrivial }
let _: @differentiable(reverse) (Self) -> Float = { $0.differentiableWrapped }
}
static func testSetters() {
let _: @differentiable(reverse) (inout Self, Float) -> Void =
{ $0.trivial = $1 }
let _: @differentiable(reverse) (inout Self, Tracked<Float>) -> Void =
{ $0.tracked = $1 }
let _: @differentiable(reverse) (inout Self, NontrivialLoadable<Float>) -> Void =
{ $0.nontrivial = $1 }
let _: @differentiable(reverse) (inout Self, Float) -> Void =
{ $0.differentiableWrapped = $1 }
}
}
struct GenericStruct<T: Differentiable>: Differentiable {
@Wrapper @SimpleWrapper var trivial: Float = 10
@Wrapper @SimpleWrapper var tracked: Tracked<Float> = 20
@Wrapper @SimpleWrapper var nontrivial: NontrivialLoadable<Float> = 30
@Wrapper @SimpleWrapper var addressOnly: T
// SR-12778: Test getter pullback for non-trivial loadable property.
static func testGetters() {
let _: @differentiable(reverse) (Self) -> Float = { $0.trivial }
let _: @differentiable(reverse) (Self) -> Tracked<Float> = { $0.tracked }
let _: @differentiable(reverse) (Self) -> NontrivialLoadable<Float> = { $0.nontrivial }
let _: @differentiable(reverse) (Self) -> T = { $0.addressOnly }
}
// SR-12779: Test setter pullback for non-trivial loadable property.
static func testSetters() {
let _: @differentiable(reverse) (inout Self, Float) -> Void =
{ $0.trivial = $1 }
let _: @differentiable(reverse) (inout Self, Tracked<Float>) -> Void =
{ $0.tracked = $1 }
let _: @differentiable(reverse) (inout Self, NontrivialLoadable<Float>) -> Void =
{ $0.nontrivial = $1 }
let _: @differentiable(reverse) (inout Self, T) -> Void =
{ $0.addressOnly = $1 }
}
}