Skip to content

Commit 6f14cf2

Browse files
committed
[AutoDiff] Fix custom derivative thunk for Optional
The patch fixes the issue #55882 and enables the nil coalescing operator (aka `??`) for Optional type.
1 parent 30984f5 commit 6f14cf2

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

lib/SILGen/SILGenPoly.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -6204,10 +6204,13 @@ SILFunction *SILGenModule::getOrCreateCustomDerivativeThunk(
62046204
arguments.push_back(indErrorRes.getLValueAddress());
62056205
forwardFunctionArguments(thunkSGF, loc, fnRefType, params, arguments);
62066206

6207+
SubstitutionMap subs = thunk->getForwardingSubstitutionMap();
6208+
SILType substFnType = fnRef->getType().substGenericArgs(
6209+
M, subs, thunk->getTypeExpansionContext());
6210+
62076211
// Apply function argument.
6208-
auto apply = thunkSGF.emitApplyWithRethrow(
6209-
loc, fnRef, /*substFnType*/ fnRef->getType(),
6210-
thunk->getForwardingSubstitutionMap(), arguments);
6212+
auto apply =
6213+
thunkSGF.emitApplyWithRethrow(loc, fnRef, substFnType, subs, arguments);
62116214

62126215
// Self reordering thunk is necessary if wrt at least two parameters,
62136216
// including self.
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify %s | %FileCheck %s
2+
3+
import _Differentiation
4+
5+
// CHECK: sil @test_nil_coalescing
6+
// CHECK: bb0(%{{.*}} : $*T, %[[ARG_OPT:.*]] : $*Optional<T>, %[[ARG_PB:.*]] :
7+
// CHECK: $@noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>):
8+
// CHECK: %[[ALLOC_OPT:.*]] = alloc_stack $Optional<T>
9+
// CHECK: copy_addr %[[ARG_OPT]] to [init] %[[ALLOC_OPT]] : $*Optional<T>
10+
// CHECK: switch_enum_addr %[[ALLOC_OPT]] : $*Optional<T>, case #Optional.some!enumelt: {{.*}}, case #Optional.none!enumelt: {{.*}}
11+
// CHECK: try_apply %[[ARG_PB]](%{{.*}}) : $@noescape @callee_guaranteed @substituted <τ_0_0> () -> (@out τ_0_0, @error any Error) for <T>, normal {{.*}}, error {{.*}}
12+
//
13+
@_silgen_name("test_nil_coalescing")
14+
@derivative(of: ??)
15+
@usableFromInline
16+
func nilCoalescing<T: Differentiable>(optional: T?, defaultValue: @autoclosure () throws -> T)
17+
rethrows -> (value: T, pullback: (T.TangentVector) -> Optional<T>.TangentVector)
18+
{
19+
let hasValue = optional != nil
20+
let value = try optional ?? defaultValue()
21+
func pullback(_ v: T.TangentVector) -> Optional<T>.TangentVector {
22+
return hasValue ? .init(v) : .zero
23+
}
24+
return (value, pullback)
25+
}

0 commit comments

Comments
 (0)