// 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 { var wrappedValue: Value // stored property } @propertyWrapper struct Wrapper { 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 { 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 = 20 @Wrapper @SimpleWrapper var nontrivial: NontrivialLoadable = 30 // https://github.com/apple/swift/issues/55245 // 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 = { $0.tracked } let _: @differentiable(reverse) (Self) -> NontrivialLoadable = { $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) -> Void = { $0.tracked = $1 } let _: @differentiable(reverse) (inout Self, NontrivialLoadable) -> Void = { $0.nontrivial = $1 } let _: @differentiable(reverse) (inout Self, Float) -> Void = { $0.differentiableWrapped = $1 } } } struct GenericStruct: Differentiable { @Wrapper @SimpleWrapper var trivial: Float = 10 @Wrapper @SimpleWrapper var tracked: Tracked = 20 @Wrapper @SimpleWrapper var nontrivial: NontrivialLoadable = 30 @Wrapper @SimpleWrapper var addressOnly: T // https://github.com/apple/swift/issues/55223 // Test getter pullback for non-trivial loadable property. static func testGetters() { let _: @differentiable(reverse) (Self) -> Float = { $0.trivial } let _: @differentiable(reverse) (Self) -> Tracked = { $0.tracked } let _: @differentiable(reverse) (Self) -> NontrivialLoadable = { $0.nontrivial } let _: @differentiable(reverse) (Self) -> T = { $0.addressOnly } } // https://github.com/apple/swift/issues/55224 // 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) -> Void = { $0.tracked = $1 } let _: @differentiable(reverse) (inout Self, NontrivialLoadable) -> Void = { $0.nontrivial = $1 } let _: @differentiable(reverse) (inout Self, T) -> Void = { $0.addressOnly = $1 } } }