When the differentiation pass is processing `gradient(at: 0, in: f)`, it finds the differentiability config arising from the `@derivative(of: f)`, and creates a corresponding differentiability witness declaration.
The linker tries to link references to that witness to an actual definition.
There is no actual definition because the witness linkage is PublicNonABI, which means that the witness does not get emitted into the library.
Some possible fixes are:
Make it so that the differentiability witness is Public instead of PublicNonABI. An obstacle for this approach is that TBDGen currently bases its decision on whether to emit a TBD entry on the linkage of the original function. So TBD doesn't won't emit a TBD entry for the witness for a PublicNonABI function. We could overcome this obstacle by teaching TBDGen to use the linkage of the derivative function instead of the linkage of the original function.
Teach the differentiation pass about PublicNonABI witnesses. Specifically:
Put information about the witness linkage in the `DerivativeFunctionConfigurationList`.
Make the pass create a decl with the appropriate linkage based on that information.
Teach something to deserialize these witnesses. (Maybe SIL/Linker.cpp is the correct place to do this, if the linking pass runs after differentiation. However, if the linking pass runs before differentiation, maybe we'll need the differentiation pass to deserialize these).
My initial thought is that the second approach is better because we want the visibility/linkage/etc of the derivative functions to always be as close to the original functions as possible.
The text was updated successfully, but these errors were encountered: