mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[AutoDiff upstream] Add Differentiable protocol derived conformances. (#30671)
Add `AdditiveArithmetic` derived conformances for structs and classes, gated by
the `-enable-experimental-differentiable-programming` flag.
Structs and classes whose stored properties all conform to `Differentiable` can
derive `Differentiable`:
- `associatedtype TangentVector: Differentiable & AdditiveArithmetic`
- Member `TangentVector` structs are synthesized whose stored properties are
all `var` stored properties that conform to `Differentiable` and that are
not `@noDerivative`.
- `mutating func move(along: TangentVector)`
The `@noDerivative` attribute may be declared on stored properties to opt out of
inclusion in synthesized `TangentVector` structs.
Some stored properties cannot be used in `TangentVector` struct synthesis and
are implicitly marked as `@noDerivative`, with a warning:
- `let` stored properties.
- These cannot be updated by `mutating func move(along: TangentVector)`.
- Non-`Differentiable`-conforming stored properties.
`@noDerivative` also implies `@_semantics("autodiff.nonvarying")`, which is
relevant for differentiable activity analysis.
Add type-checking and SILGen tests.
Resolves TF-845.
This commit is contained in:
@@ -1369,3 +1369,21 @@ bool swift::hasLetStoredPropertyWithInitialValue(NominalTypeDecl *nominal) {
|
||||
return v->isLet() && v->hasInitialValue();
|
||||
});
|
||||
}
|
||||
|
||||
void swift::addFixedLayoutAttr(NominalTypeDecl *nominal) {
|
||||
auto &C = nominal->getASTContext();
|
||||
// If nominal already has `@_fixed_layout`, return.
|
||||
if (nominal->getAttrs().hasAttribute<FixedLayoutAttr>())
|
||||
return;
|
||||
auto access = nominal->getEffectiveAccess();
|
||||
// If nominal does not have at least internal access, return.
|
||||
if (access < AccessLevel::Internal)
|
||||
return;
|
||||
// If nominal is internal, it should have the `@usableFromInline` attribute.
|
||||
if (access == AccessLevel::Internal &&
|
||||
!nominal->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
|
||||
nominal->getAttrs().add(new (C) UsableFromInlineAttr(/*Implicit*/ true));
|
||||
}
|
||||
// Add `@_fixed_layout` to the nominal.
|
||||
nominal->getAttrs().add(new (C) FixedLayoutAttr(/*Implicit*/ true));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user