Skip to content

Commit 19297ed

Browse files
authored
---
yaml --- r: 277500 b: refs/heads/tensorflow-merge c: 1335015 h: refs/heads/master
1 parent 926a272 commit 19297ed

File tree

4 files changed

+55
-23
lines changed

4 files changed

+55
-23
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ refs/tags/swift-4.2-DEVELOPMENT-SNAPSHOT-2018-10-29-a: 1b087071edaea398480fb778e
11241124
refs/tags/swift-4.2-DEVELOPMENT-SNAPSHOT-2018-10-30-a: 8bc9e108e1480d9217299984e428c601c7aaac75
11251125
refs/tags/swift-4.2.1-RELEASE: 02a6ca969ea1387475b6caeb69c31186df7d30b6
11261126
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-11-01-a: 3b0299288f8287094b9ef587f46df54f42a347af
1127-
refs/heads/tensorflow-merge: dc23a97dd75965198ad97637175a52bd47e3cbd2
1127+
refs/heads/tensorflow-merge: 133501508aa0a8d80caa210d6a25e4d757750952
11281128
refs/heads/TensorFlowLite: b91446471276e37bbfe64767c875f3c7f7102954
11291129
refs/heads/ad-side-effects: 19e0c0de1f59b0929c381925df2e8c72cdf4a728
11301130
refs/heads/add-test-for-asan-compiler-crash: 3cdeecffb47bf28707b299fa2b5bdf0769a4a826

branches/tensorflow-merge/lib/Sema/DerivedConformanceDifferentiable.cpp

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,18 @@ bool DerivedConformance::canDeriveDifferentiable(NominalTypeDecl *nominal,
148148
if (!structDecl)
149149
return nullptr;
150150
// Valid candidate must either:
151-
// - Be implicit (previously synthesized).
152-
// - Equal nominal (and conform to `AdditiveArithmetic` if flag is true).
151+
// 1. Be implicit (previously synthesized).
153152
if (structDecl->isImplicit())
154153
return structDecl;
154+
// 2. Equal nominal's implicit parent.
155+
// This can occur during mutually recursive constraints. Example:
156+
// `X == X.TangentVector, X.CotangentVector.CotangentVector == X`.
157+
if (nominal->isImplicit() && structDecl == nominal->getDeclContext() &&
158+
TypeChecker::conformsToProtocol(structDecl->getDeclaredInterfaceType(),
159+
diffableProto, DC,
160+
ConformanceCheckFlags::Used))
161+
return structDecl;
162+
// 3. Equal nominal (and conform to `AdditiveArithmetic` if flag is true).
155163
if (structDecl == nominal) {
156164
if (!checkAdditiveArithmetic)
157165
return structDecl;
@@ -815,12 +823,12 @@ static void addAssociatedTypeAliasDecl(Identifier name,
815823
auto lookup = nominal->lookupDirect(name);
816824
assert(lookup.size() < 2 &&
817825
"Expected at most one associated type named member");
818-
// If implicit typealias with the given name already exists in source
826+
// If implicit type declaration with the given name already exists in source
819827
// struct, return it.
820828
if (lookup.size() == 1) {
821-
auto existingAlias = dyn_cast<TypeAliasDecl>(lookup.front());
822-
assert(existingAlias && existingAlias->isImplicit() &&
823-
"Expected lookup result to be an implicit typealias");
829+
auto existingTypeDecl = dyn_cast<TypeDecl>(lookup.front());
830+
assert(existingTypeDecl && existingTypeDecl->isImplicit() &&
831+
"Expected lookup result to be an implicit type declaration");
824832
return;
825833
}
826834
// Otherwise, create a new typealias.
@@ -898,31 +906,31 @@ getOrSynthesizeAssociatedStructType(DerivedConformance &derived,
898906
auto *nominal = derived.Nominal;
899907
auto &C = nominal->getASTContext();
900908

901-
// Get or synthesize `TangentVector`, `CotangentVector`, and
902-
// `AllDifferentiableVariables` structs at once. Synthesizing all three
903-
// structs at once is necessary in order to correctly set their mutually
904-
// recursive associated types.
909+
// Get or synthesize `AllDifferentiableVariables`, `TangentVector`, and
910+
// `CotangentVector` structs at once. Synthesizing all three structs at once
911+
// is necessary in order to correctly set their mutually recursive associated
912+
// types.
913+
auto allDiffableVarsStructSynthesis =
914+
getOrSynthesizeSingleAssociatedStruct(derived,
915+
C.Id_AllDifferentiableVariables);
916+
auto *allDiffableVarsStruct = allDiffableVarsStructSynthesis.first;
917+
if (!allDiffableVarsStruct)
918+
return nullptr;
919+
bool freshlySynthesized = allDiffableVarsStructSynthesis.second;
920+
905921
auto tangentStructSynthesis =
906922
getOrSynthesizeSingleAssociatedStruct(derived, C.Id_TangentVector);
907923
auto *tangentStruct = tangentStructSynthesis.first;
908-
bool freshlySynthesized = tangentStructSynthesis.second;
909924
if (!tangentStruct)
910925
return nullptr;
926+
freshlySynthesized |= tangentStructSynthesis.second;
911927

912928
auto cotangentStructSynthesis =
913929
getOrSynthesizeSingleAssociatedStruct(derived, C.Id_CotangentVector);
914930
auto *cotangentStruct = cotangentStructSynthesis.first;
915931
if (!cotangentStruct)
916932
return nullptr;
917-
assert(freshlySynthesized == cotangentStructSynthesis.second);
918-
919-
auto allDiffableVarsStructSynthesis =
920-
getOrSynthesizeSingleAssociatedStruct(derived,
921-
C.Id_AllDifferentiableVariables);
922-
auto *allDiffableVarsStruct = allDiffableVarsStructSynthesis.first;
923-
if (!allDiffableVarsStruct)
924-
return nullptr;
925-
assert(freshlySynthesized == allDiffableVarsStructSynthesis.second);
933+
freshlySynthesized |= cotangentStructSynthesis.second;
926934

927935
// When all structs are freshly synthesized, we check emit warnings for
928936
// implicit `@noDerivative` members. Checking for fresh synthesis is necessary
@@ -953,9 +961,9 @@ getOrSynthesizeAssociatedStructType(DerivedConformance &derived,
953961
addAssociatedTypeAliasDecl(C.Id_AllDifferentiableVariables,
954962
cotangentStruct, cotangentStruct, TC);
955963

964+
TC.validateDecl(allDiffableVarsStruct);
956965
TC.validateDecl(tangentStruct);
957966
TC.validateDecl(cotangentStruct);
958-
TC.validateDecl(allDiffableVarsStruct);
959967

960968
// Sanity checks for synthesized structs.
961969
assert(DerivedConformance::canDeriveAdditiveArithmetic(tangentStruct,
@@ -1082,7 +1090,7 @@ deriveDifferentiable_AssociatedStruct(DerivedConformance &derived,
10821090
if (allMembersAssocTypesEqualsSelf) {
10831091
auto allDiffableVarsStructSynthesis = getOrSynthesizeSingleAssociatedStruct(
10841092
derived, C.Id_AllDifferentiableVariables);
1085-
auto allDiffableVarsStruct = allDiffableVarsStructSynthesis.first;
1093+
auto *allDiffableVarsStruct = allDiffableVarsStructSynthesis.first;
10861094
auto freshlySynthesized = allDiffableVarsStructSynthesis.second;
10871095
// `AllDifferentiableVariables` must conform to `AdditiveArithmetic`.
10881096
// This should be guaranteed.

branches/tensorflow-merge/test/AutoDiff/derived_differentiable_properties.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,23 @@ struct TestKeyPathIterable : Differentiable, KeyPathIterable {
6565
// CHECK-AST: internal typealias CotangentVector = TestKeyPathIterable.AllDifferentiableVariables
6666
// CHECK-AST: internal typealias TangentVector = TestKeyPathIterable.AllDifferentiableVariables
6767
// CHECK-AST: internal typealias CotangentVector = TestKeyPathIterable.AllDifferentiableVariables
68+
69+
struct GenericCotanMember<T : Differentiable> : Differentiable, AdditiveArithmetic {
70+
var x: T.CotangentVector
71+
}
72+
73+
// TODO(TF-316): Revisit after `Differentiable` derived conformances behavior is standardized.
74+
// `AllDifferentiableVariables` and `CotangentVector` structs need not both be synthesized.
75+
76+
// CHECK-AST-LABEL: @_fieldwiseDifferentiable internal struct GenericCotanMember<T> : Differentiable, AdditiveArithmetic where T : Differentiable {
77+
// CHECK-AST: var x: T.CotangentVector
78+
// CHECK-AST: internal init(x: T.CotangentVector)
79+
// CHECK-AST: internal typealias TangentVector = GenericCotanMember<T>
80+
// CHECK-AST-LABEL: @_fieldwiseDifferentiable internal struct AllDifferentiableVariables : Differentiable
81+
// CHECK-AST: internal typealias TangentVector = GenericCotanMember<T>
82+
// CHECK-AST: internal typealias CotangentVector = GenericCotanMember<T>.CotangentVector
83+
// CHECK-AST: internal typealias AllDifferentiableVariables = GenericCotanMember<T>.AllDifferentiableVariables
84+
// CHECK-AST-LABEL: @_fieldwiseDifferentiable internal struct CotangentVector : Differentiable, AdditiveArithmetic
85+
// CHECK-AST: internal typealias TangentVector = GenericCotanMember<T>.CotangentVector
86+
// CHECK-AST: internal typealias CotangentVector = GenericCotanMember<T>
87+
// CHECK-AST: internal typealias AllDifferentiableVariables = GenericCotanMember<T>.CotangentVector

branches/tensorflow-merge/test/Sema/struct_differentiable.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ extension GenericConstrained : Differentiable
247247
// expected-warning @+1 {{stored property '_buffer' has no derivative because it does not conform to 'Differentiable'; add '@noDerivative' to make it explicit}}
248248
extension Array : Differentiable where Element : Differentiable {}
249249

250+
struct TF_260<T : Differentiable> : Differentiable & AdditiveArithmetic {
251+
var x: T.CotangentVector
252+
}
253+
250254
// Test errors.
251255

252256
// Test manually customizing vector space types.

0 commit comments

Comments
 (0)