// RUN: %target-swift-emit-sil -Xllvm -debug-only=differentiation -o /dev/null 2>&1 %s | %FileCheck %s

// The differentiability witness for y in s(h:) will be generated by silgen. However, later the capture
// promotion pass would specialize it since it only captures an integer and therefore does not need to
// box the capture. Ensure we create differentiability witness for specialized function. In addition to
// this, since the original function is not used anymore, the body of it is removed (with only unreachable
// terminator inside). Remove original differentiability witness as it would lead to non-differentiable
// diagnostics further on.

// CHECK-LABEL: differentiability witness for specialized y #1 (_:) in s(h:)
// CHECK: sil_differentiability_witness private [reverse] [parameters 0] [results 0] @$s{{.*}} : $@convention(thin) (@guaranteed W, Int) -> @owned W {
// CHECK-NOT: sil_differentiability_witness private [reverse] [parameters 0] [results 0] @$s{{.*}} : $@convention(thin) (@guaranteed W, @guaranteed { var Int }) -> @owned W {

import _Differentiation
struct B: Differentiable{}
struct X { var j = [Float]()}
struct W: Differentiable {
    @noDerivative var z: X
    var h: B
}
func o<T, R>(_ x: T, _ f: @differentiable(reverse) (T) -> R) -> R {f(x)}
func m<T, R>(_ f: @escaping @differentiable(reverse) (T) -> R) -> @differentiable(reverse) (T) -> R {{ x in o(x, f) }}
@differentiable(reverse)
 func s(h: B) -> B {
    var (_, e) = (0,0)
    @differentiable(reverse)
    func y(_ i: W) -> W {
        let _ = e;
        return i
    }
    let w = m(y)
    return B()
}
