Summary
[ForwardDerivativeOf] cannot resolve a shaped generic function when the target name also has a
catch-all generic overload. The same failure occurs when the catch-all generic is the only target
and the derivative applies to a constrained subset of its specializations.
This blocks adding interface-constrained generic wrappers for core-module functions such as
sin: the wrapper makes the existing vector/matrix [ForwardDerivativeOf(sin)] declarations fail
while loading the builtin module.
Minimal reproduction
#ifndef OMIT_SHAPED_OVERLOAD
__generic<T : __BuiltinFloatingPointType, let N : int>
[Differentiable]
vector<T, N> testFunction(vector<T, N> value)
{
return value * value;
}
#endif
#ifndef OMIT_GENERIC_OVERLOAD
[Differentiable]
T testFunction<T : IFloat>(T value)
{
return value * value;
}
#endif
__generic<T : __BuiltinFloatingPointType, let N : int>
[ForwardDerivativeOf(testFunction)]
DifferentialPair<vector<T, N>> testFunctionForward(
DifferentialPair<vector<T, N>> value)
{
return diffPair(
testFunction(value.p),
T(2.0) * value.p * value.d);
}
[shader("compute")]
[numthreads(1, 1, 1)]
void main()
{}
Compile with:
slangc repro.slang -target spirv -entry main -stage compute -o repro.spv
The default configuration produces:
error[E31148]: cannot resolve derivative function
--> repro.slang:19:2
|
19 | [ForwardDerivativeOf(testFunction)]
| ^^^^^^^^^^^^^^^^^^^ cannot resolve the custom derivative function
Control results:
| Configuration |
Result |
| Both overloads present |
E31148 |
-DOMIT_GENERIC_OVERLOAD (only the shaped generic) |
Compiles |
-DOMIT_SHAPED_OVERLOAD (only the catch-all generic) |
E31148 |
Tested with slangc 2026.14.1-80-gd4c72aab0 on Windows.
Expected behavior / design question
For the overload-set case, the compiler should either preserve the association with the exactly
shaped generic overload, or provide a way for the attribute to explicitly select that overload.
If both declarations are intentionally considered applicable, the diagnostic should identify the
ambiguity and its candidates rather than reporting only that the derivative cannot be resolved.
For the catch-all-only case, the derivative is an override for the subset of specializations where
the primal's T is vector<Element, N>. Supporting this kind of constrained derivative override
was an explicit goal of #6486.
Why this appears related to the autodiff-overhaul design
#6486 describes derivative overrides that apply to a subset of a generic function's
specializations and says the mapping must be constructed at the relevant use site using the
specialization arguments. Its design discussion also proposed resolving a *DerivativeOf
OverloadedExpr by testing the candidates through constraint solving. The issue was closed by
#9808, whose description says the new interface/extension model supports constrained generic
custom derivatives and translates the legacy derivative attributes into that model.
The behavior above suggests that this support is incomplete in the legacy
[ForwardDerivativeOf(...)] translation/checking path, or that the implemented model still lacks
a necessary overload-disambiguation rule. The still-open #10107 records another unresolved
*DerivativeOf overload-selection problem (a synthesized backward derivative being selected over
a user-defined one), although that is not the same reproducer.
Core-module impact
In a numeric-interface design spike, adding a public wrapper equivalent to:
[Differentiable]
T sin<T : IReal>(T value)
{
return value.sin();
}
beside the existing scalar/vector/matrix sin overloads makes the existing generated
[ForwardDerivativeOf(sin)] declarations fail with E31148. The spike can compile only by renaming
the shaped builtin implementations, attaching their derivatives to those private names, and
routing the public surface through the new generic wrapper. That workaround should not be required
merely to add a generic public overload.
Related: #6486, #9808, #10107.
Summary
[ForwardDerivativeOf]cannot resolve a shaped generic function when the target name also has acatch-all generic overload. The same failure occurs when the catch-all generic is the only target
and the derivative applies to a constrained subset of its specializations.
This blocks adding interface-constrained generic wrappers for core-module functions such as
sin: the wrapper makes the existing vector/matrix[ForwardDerivativeOf(sin)]declarations failwhile loading the builtin module.
Minimal reproduction
Compile with:
The default configuration produces:
Control results:
-DOMIT_GENERIC_OVERLOAD(only the shaped generic)-DOMIT_SHAPED_OVERLOAD(only the catch-all generic)Tested with
slangc 2026.14.1-80-gd4c72aab0on Windows.Expected behavior / design question
For the overload-set case, the compiler should either preserve the association with the exactly
shaped generic overload, or provide a way for the attribute to explicitly select that overload.
If both declarations are intentionally considered applicable, the diagnostic should identify the
ambiguity and its candidates rather than reporting only that the derivative cannot be resolved.
For the catch-all-only case, the derivative is an override for the subset of specializations where
the primal's
Tisvector<Element, N>. Supporting this kind of constrained derivative overridewas an explicit goal of #6486.
Why this appears related to the autodiff-overhaul design
#6486 describes derivative overrides that apply to a subset of a generic function's
specializations and says the mapping must be constructed at the relevant use site using the
specialization arguments. Its design discussion also proposed resolving a
*DerivativeOfOverloadedExprby testing the candidates through constraint solving. The issue was closed by#9808, whose description says the new interface/extension model supports constrained generic
custom derivatives and translates the legacy derivative attributes into that model.
The behavior above suggests that this support is incomplete in the legacy
[ForwardDerivativeOf(...)]translation/checking path, or that the implemented model still lacksa necessary overload-disambiguation rule. The still-open #10107 records another unresolved
*DerivativeOfoverload-selection problem (a synthesized backward derivative being selected overa user-defined one), although that is not the same reproducer.
Core-module impact
In a numeric-interface design spike, adding a public wrapper equivalent to:
beside the existing scalar/vector/matrix
sinoverloads makes the existing generated[ForwardDerivativeOf(sin)]declarations fail with E31148. The spike can compile only by renamingthe shaped builtin implementations, attaching their derivatives to those private names, and
routing the public surface through the new generic wrapper. That workaround should not be required
merely to add a generic public overload.
Related: #6486, #9808, #10107.