mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
When SILGenWitnessTable creates a decl ref for the witness of a derivative function requirement, it is using the requirement's derivative generic signature in the resulting witness decl ref. This is wrong because the witness may have a different derivative generic signature than the requirement, leading to a crash. This bug was never discovered because GSB's dark magic made it "just work", until requirement machine. The fix is to store the matched witness derivative generic signature in `Witness` during type checking, and during witness table generation, use the witness' generic signature to create a witness decl ref. Resolves rdar://84716758, rdar://84213107 and rdar://84987079.
45 lines
1.2 KiB
Swift
45 lines
1.2 KiB
Swift
// RUN: %target-build-swift %s
|
|
|
|
import _Differentiation
|
|
|
|
public protocol Layer: Differentiable {
|
|
associatedtype Input: Differentiable
|
|
associatedtype Output: Differentiable
|
|
@differentiable(reverse, wrt: (self, input))
|
|
@differentiable(reverse, wrt: input)
|
|
func callAsFunction(_ input: Input) -> Output
|
|
}
|
|
|
|
// Test for explicitly declared `@differentiable` attributes.
|
|
public class Function1<Input: Differentiable, Output: Differentiable>: Layer {
|
|
@noDerivative public let body: @differentiable(reverse) (Input) -> Output
|
|
|
|
public init(_ body: @escaping @differentiable(reverse) (Input) -> Output) {
|
|
self.body = body
|
|
}
|
|
|
|
@differentiable(reverse, wrt: (self, input))
|
|
@differentiable(reverse, wrt: input)
|
|
public func callAsFunction(_ input: Input) -> Output {
|
|
body(input)
|
|
}
|
|
|
|
@differentiable(reverse, wrt: x where T: Differentiable)
|
|
public func foo<T>(x: T) -> T {
|
|
x
|
|
}
|
|
}
|
|
|
|
// Test for implicitly generated `@differentiable` attributes.
|
|
class Function2<Input: Differentiable, Output: Differentiable>: Layer {
|
|
@noDerivative let body: @differentiable(reverse) (Input) -> Output
|
|
|
|
init(_ body: @escaping @differentiable(reverse) (Input) -> Output) {
|
|
self.body = body
|
|
}
|
|
|
|
func callAsFunction(_ input: Input) -> Output {
|
|
body(input)
|
|
}
|
|
}
|