Skip to content

Commit e763422

Browse files
asavonicasl
authored andcommitted
[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 4c2dc5e commit e763422

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

lib/SILGen/SILGenPoly.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6305,10 +6305,13 @@ SILFunction *SILGenModule::getOrCreateCustomDerivativeThunk(
63056305
arguments.push_back(indErrorRes.getLValueAddress());
63066306
forwardFunctionArguments(thunkSGF, loc, fnRefType, params, arguments);
63076307

6308+
SubstitutionMap subs = thunk->getForwardingSubstitutionMap();
6309+
SILType substFnType = fnRef->getType().substGenericArgs(
6310+
M, subs, thunk->getTypeExpansionContext());
6311+
63086312
// Apply function argument.
6309-
auto apply = thunkSGF.emitApplyWithRethrow(
6310-
loc, fnRef, /*substFnType*/ fnRef->getType(),
6311-
thunk->getForwardingSubstitutionMap(), arguments);
6313+
auto apply =
6314+
thunkSGF.emitApplyWithRethrow(loc, fnRef, substFnType, subs, arguments);
63126315

63136316
// Self reordering thunk is necessary if wrt at least two parameters,
63146317
// including self.
Lines changed: 25 additions & 0 deletions
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)