@@ -40,7 +40,7 @@ using namespace swift;
40
40
// / If the given property is a `var`, return true because `move(by:)` can be
41
41
// / invoked regardless. Otherwise, return true if and only if the property's
42
42
// / type's 'Differentiable.move(by:)' witness is non-mutating.
43
- static bool canInvokeMoveAlongOnProperty (
43
+ static bool canInvokeMoveByOnProperty (
44
44
VarDecl *vd, ProtocolConformanceRef diffableConformance) {
45
45
assert (diffableConformance && " Property must conform to 'Differentiable'" );
46
46
// `var` always supports `move(by:)` since it is mutable.
@@ -64,7 +64,7 @@ static void
64
64
getStoredPropertiesForDifferentiation (
65
65
NominalTypeDecl *nominal, DeclContext *DC,
66
66
SmallVectorImpl<VarDecl *> &result,
67
- bool includeLetPropertiesWithNonmutatingMoveAlong = false ) {
67
+ bool includeLetPropertiesWithNonmutatingMoveBy = false ) {
68
68
auto &C = nominal->getASTContext ();
69
69
auto *diffableProto = C.getProtocol (KnownProtocolKind::Differentiable);
70
70
for (auto *vd : nominal->getStoredProperties ()) {
@@ -90,8 +90,8 @@ getStoredPropertiesForDifferentiation(
90
90
// Skip `let` stored properties with a mutating `move(by:)` if requested.
91
91
// `mutating func move(by:)` cannot be synthesized to update `let`
92
92
// properties.
93
- if (!includeLetPropertiesWithNonmutatingMoveAlong &&
94
- !canInvokeMoveAlongOnProperty (vd, conformance))
93
+ if (!includeLetPropertiesWithNonmutatingMoveBy &&
94
+ !canInvokeMoveByOnProperty (vd, conformance))
95
95
continue ;
96
96
result.push_back (vd);
97
97
}
@@ -450,9 +450,9 @@ getOrSynthesizeTangentVectorStruct(DerivedConformance &derived, Identifier id) {
450
450
auto *tangentProperty = new (C) VarDecl (
451
451
member->isStatic (), member->getIntroducer (),
452
452
/* NameLoc*/ SourceLoc (), member->getName (), structDecl);
453
- tangentProperty-> setSynthesized ();
454
- // Note: `tangentProperty` is not marked as implicit here, because that
455
- // incorrectly affects memberwise initializer synthesis .
453
+ // Note: ` tangentProperty` is not marked as implicit or synthesized here,
454
+ // because that incorrectly affects memberwise initializer synthesis and
455
+ // causes the type checker to not guarantee the order of these members .
456
456
auto memberContextualType =
457
457
parentDC->mapTypeIntoContext (member->getValueInterfaceType ());
458
458
auto memberTanType =
@@ -507,20 +507,27 @@ getOrSynthesizeTangentVectorStruct(DerivedConformance &derived, Identifier id) {
507
507
}
508
508
}
509
509
510
- // If nominal type is `@_fixed_layout`, also mark `TangentVector` struct as
511
- // `@_fixed_layout`.
512
- if (nominal->getAttrs ().hasAttribute <FixedLayoutAttr>())
513
- addFixedLayoutAttr (structDecl);
514
-
515
- // If nominal type is `@frozen`, also mark `TangentVector` struct as
516
- // `@frozen`.
510
+ // If nominal type is `@frozen`, also mark `TangentVector` struct.
517
511
if (nominal->getAttrs ().hasAttribute <FrozenAttr>())
518
512
structDecl->getAttrs ().add (new (C) FrozenAttr (/* implicit*/ true ));
519
-
520
- // If nominal type is `@usableFromInline`, also mark `TangentVector` struct as
521
- // `@usableFromInline`.
522
- if (nominal->getAttrs ().hasAttribute <UsableFromInlineAttr>())
513
+
514
+ // Add `typealias TangentVector = Self` so that the `TangentVector` itself
515
+ // won't need its own conformance derivation.
516
+ auto *tangentEqualsSelfAlias = new (C) TypeAliasDecl (
517
+ SourceLoc (), SourceLoc (), C.Id_TangentVector , SourceLoc (),
518
+ /* GenericParams*/ nullptr , structDecl);
519
+ tangentEqualsSelfAlias->setUnderlyingType (structDecl->getSelfTypeInContext ());
520
+ tangentEqualsSelfAlias->setAccess (structDecl->getFormalAccess ());
521
+ tangentEqualsSelfAlias->setImplicit ();
522
+ tangentEqualsSelfAlias->setSynthesized ();
523
+ structDecl->addMember (tangentEqualsSelfAlias);
524
+
525
+ // If nominal type is `@usableFromInline`, also mark `TangentVector` struct.
526
+ if (nominal->getAttrs ().hasAttribute <UsableFromInlineAttr>()) {
523
527
structDecl->getAttrs ().add (new (C) UsableFromInlineAttr (/* implicit*/ true ));
528
+ tangentEqualsSelfAlias->getAttrs ().add (
529
+ new (C) UsableFromInlineAttr (/* implicit*/ true ));
530
+ }
524
531
525
532
// The implicit memberwise constructor must be explicitly created so that it
526
533
// can called in `AdditiveArithmetic` and `Differentiable` methods. Normally,
@@ -593,7 +600,7 @@ static void checkAndDiagnoseImplicitNoDerivative(ASTContext &Context,
593
600
TypeChecker::conformsToProtocol (varType, diffableProto, nominal);
594
601
// If stored property should not be diagnosed, continue.
595
602
if (diffableConformance &&
596
- canInvokeMoveAlongOnProperty (vd, diffableConformance))
603
+ canInvokeMoveByOnProperty (vd, diffableConformance))
597
604
continue ;
598
605
// Otherwise, add an implicit `@noDerivative` attribute.
599
606
vd->getAttrs ().add (new (Context) NoDerivativeAttr (/* Implicit*/ true ));
0 commit comments