blob: 5b79682623f81d7e1ebf2b0436a4cab1e185887c [file] [log] [blame]
// 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 (Self) -> Float = { $0.trivial }
let _: @differentiable (Self) -> Tracked<Float> = { $0.tracked }
let _: @differentiable (Self) -> NontrivialLoadable<Float> = { $0.nontrivial }
let _: @differentiable (Self) -> Float = { $0.differentiableWrapped }
}
static func testSetters() {
let _: @differentiable (inout Self, Float) -> Void =
{ $0.trivial = $1 }
let _: @differentiable (inout Self, Tracked<Float>) -> Void =
{ $0.tracked = $1 }
let _: @differentiable (inout Self, NontrivialLoadable<Float>) -> Void =
{ $0.nontrivial = $1 }
let _: @differentiable (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 (Self) -> Float = { $0.trivial }
let _: @differentiable (Self) -> Tracked<Float> = { $0.tracked }
let _: @differentiable (Self) -> NontrivialLoadable<Float> = { $0.nontrivial }
let _: @differentiable (Self) -> T = { $0.addressOnly }
}
// SR-12779: Test setter pullback for non-trivial loadable property.
static func testSetters() {
let _: @differentiable (inout Self, Float) -> Void =
{ $0.trivial = $1 }
let _: @differentiable (inout Self, Tracked<Float>) -> Void =
{ $0.tracked = $1 }
let _: @differentiable (inout Self, NontrivialLoadable<Float>) -> Void =
{ $0.nontrivial = $1 }
let _: @differentiable (inout Self, T) -> Void =
{ $0.addressOnly = $1 }
}
}