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
|
// RUN: %target-swift-emit-sil -verify %s
import _Differentiation
public enum DiffEnum<Wrapped>: ExpressibleByNilLiteral {
case none
case some(Wrapped)
@_transparent
public init(_ some: Wrapped) { self = .some(some) }
@_transparent
public init(nilLiteral: ()) {
self = .none
}
}
extension DiffEnum: Differentiable where Wrapped: Differentiable {
public enum TangentVector: Differentiable, AdditiveArithmetic {
case none
case some(Wrapped.TangentVector)
public typealias TangentVector = Self
public init(_ value: Wrapped.TangentVector?) {
switch value {
case .some(let y):
self = .some(y)
case .none:
self = .none
}
}
public static var zero: Self {
return Self(.zero)
}
public static func + (lhs: Self, rhs: Self) -> Self {
switch (lhs, rhs) {
case let (.some(x), .some(y)): return Self(x + y)
case let (.some(x), .none): return Self(x)
case let (.none, .some(y)): return Self(y)
case (.none, .none): return .none
}
}
public static func - (lhs: Self, rhs: Self) -> Self {
switch (lhs, rhs) {
case let (.some(x), .some(y)): return .some(x - y)
case let (.some(x), .none): return .some(x)
case let (.none, .some(y)): return .some(.zero - y)
case (.none, .none): return .none
}
}
public mutating func move(by offset: TangentVector) {
}
}
public mutating func move(by offset: TangentVector) {
}
// expected-error @+2 {{expression is not differentiable}}
// expected-note @+1 {{differentiating enum values is not yet supported}}
public func f() -> Wrapped {
switch (self) {
case let .some(v): return v
default: fatalError()
}
}
}
// expected-error @+2 {{function is not differentiable}}
// expected-note @+2 {{when differentiating this function definition}}
@differentiable(reverse)
func enumNotSupported<Element>(x: Element) -> Element where Element: Differentiable {
// expected-note @+1 {{differentiating enum values is not yet supported}}
let e = DiffEnum<Element>.some(x)
return e.f()
}
@differentiable(reverse)
func enumOptional<Element>(x: Element) -> Element? where Element: Differentiable {
return x
}
|