Hi compiler experts,

I’m working on the differentiable programming project and have a question about the best representation for `where`

clause requirements.

The `@differentiable`

attribute marks function-like declarations as being differentiable. On generic declarations, the `@differentiable`

attribute may have an associated `where`

clause with requirements for conditional differentiability. Examples:

```
@differentiable(where T: Differentiable)
func identity<T>(_ x: T) -> T { x }
struct Tensor<Scalar> { ... }
extension Tensor where Scalar: Numeric {
// Numeric operations are differentiable only if the scalar type is
// floating-point (continuous) and differentiable.
@differentiable(where Scalar: FloatingPoint & Differentiable)
static func +(lhs: Self, rhs: Self) -> Self { ... }
}
```

So far, we’ve represented these generic requirements as `ArrayRef<Requirement>`

, stored and serialized in the AST `DifferentiableAttr`

and the `SILDifferentiableAttr`

data structures. However, a common operation is to compute a “derivative generic signature” given the original declaration’s generic signature and the attribute requirements: see `getAutoDiffAssociatedFunctionGenericSignature`

. This code is duplicated in 2-3 places.

**I wonder if it makes more sense to store requirements directly as a GenericSignature or GenericEnvironment in DifferentiableAttr?** This should eliminate redundant code for computing derivative generic signatures from

`ArrayRef<Requirement>`

and the original declaration `GenericSignature`

. There is no need to distinguish original requirements vs attribute requirements.Currently, the `@differentiable`

type-checking code actually already forms a derivative `GenericSignature`

and `GenericEnvironment`

when resolving `RequirementRepr`

s during type-checking, so we can just store one of those instead of the resolved `Requirement`

s.

**I also wonder whether it's appropriate to store a GenericSignature or GenericEnvironment?** The primary use for the generic signature/environment is to remap types, which seems easier with

`GenericEnvironment`

but maybe possible with both:-
`GenericEnvironment`

:`GenericEnvironment::mapTypeIntoContext`

. Seems robust. -
`GenericSignature`

: no dedicated method for remapping types. Possible to use`Type::subst(SubstitutionMap)`

with`GenericSignature::getIdentitySubstitutionMap`

but seems less robust.