Files
swift-mirror/test/AutoDiff/compiler_crashers_fixed/rdar84716758-differentiable-protocol-witness-missing-requirements.swift
Richard Wei 1a4ea67e2c [AutoDiff] Plumb witness derivative generic signatures through SILGen.
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.
2021-11-05 10:28:33 -07:00

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)
}
}