@@ -35,6 +35,7 @@ class AnyFunctionType;
35
35
class SourceFile ;
36
36
class SILFunctionType ;
37
37
class TupleType ;
38
+ class VarDecl ;
38
39
39
40
// / A function type differentiability kind.
40
41
enum class DifferentiabilityKind : uint8_t {
@@ -459,6 +460,99 @@ class DerivativeFunctionTypeError
459
460
}
460
461
};
461
462
463
+ // / Describes the "tangent stored property" corresponding to an original stored
464
+ // / property in a `Differentiable`-conforming type.
465
+ // /
466
+ // / The tangent stored property is the stored property in the `TangentVector`
467
+ // / struct of the `Differentiable`-conforming type, with the same name as the
468
+ // / original stored property and with the original stored property's
469
+ // / `TangentVector` type.
470
+ struct TangentPropertyInfo {
471
+ struct Error {
472
+ enum class Kind {
473
+ // / The original property is `@noDerivative`.
474
+ NoDerivativeOriginalProperty,
475
+ // / The nominal parent type does not conform to `Differentiable`.
476
+ NominalParentNotDifferentiable,
477
+ // / The original property's type does not conform to `Differentiable`.
478
+ OriginalPropertyNotDifferentiable,
479
+ // / The parent `TangentVector` type is not a struct.
480
+ ParentTangentVectorNotStruct,
481
+ // / The parent `TangentVector` struct does not declare a stored property
482
+ // / with the same name as the original property.
483
+ TangentPropertyNotFound,
484
+ // / The tangent property's type is not equal to the original property's
485
+ // / `TangentVector` type.
486
+ TangentPropertyWrongType,
487
+ // / The tangent property is not a stored property.
488
+ TangentPropertyNotStored
489
+ };
490
+
491
+ // / The error kind.
492
+ Kind kind;
493
+
494
+ private:
495
+ union Value {
496
+ Type type;
497
+ Value (Type type) : type (type) {}
498
+ Value () {}
499
+ } value;
500
+
501
+ public:
502
+ Error (Kind kind) : kind(kind), value() {
503
+ assert (kind == Kind::NoDerivativeOriginalProperty ||
504
+ kind == Kind::NominalParentNotDifferentiable ||
505
+ kind == Kind::OriginalPropertyNotDifferentiable ||
506
+ kind == Kind::ParentTangentVectorNotStruct ||
507
+ kind == Kind::TangentPropertyNotFound ||
508
+ kind == Kind::TangentPropertyNotStored);
509
+ };
510
+
511
+ Error (Kind kind, Type type) : kind(kind), value(type) {
512
+ assert (kind == Kind::TangentPropertyWrongType);
513
+ };
514
+
515
+ Type getType () const {
516
+ assert (kind == Kind::TangentPropertyWrongType);
517
+ return value.type ;
518
+ }
519
+
520
+ friend bool operator ==(const Error &lhs, const Error &rhs);
521
+ };
522
+
523
+ // / The tangent stored property.
524
+ VarDecl *tangentProperty = nullptr ;
525
+
526
+ // / An optional error.
527
+ Optional<Error> error = None;
528
+
529
+ private:
530
+ TangentPropertyInfo (VarDecl *tangentProperty, Optional<Error> error)
531
+ : tangentProperty(tangentProperty), error(error) {}
532
+
533
+ public:
534
+ TangentPropertyInfo (VarDecl *tangentProperty)
535
+ : TangentPropertyInfo(tangentProperty, None) {}
536
+
537
+ TangentPropertyInfo (Error::Kind errorKind)
538
+ : TangentPropertyInfo(nullptr , Error(errorKind)) {}
539
+
540
+ TangentPropertyInfo (Error::Kind errorKind, Type errorType)
541
+ : TangentPropertyInfo(nullptr , Error(errorKind, errorType)) {}
542
+
543
+ // / Returns `true` iff this tangent property info is valid.
544
+ bool isValid () const { return tangentProperty && !error; }
545
+
546
+ explicit operator bool () const { return isValid (); }
547
+
548
+ friend bool operator ==(const TangentPropertyInfo &lhs,
549
+ const TangentPropertyInfo &rhs) {
550
+ return lhs.tangentProperty == rhs.tangentProperty && lhs.error == rhs.error ;
551
+ }
552
+ };
553
+
554
+ void simple_display (llvm::raw_ostream &OS, TangentPropertyInfo info);
555
+
462
556
// / The key type used for uniquing `SILDifferentiabilityWitness` in
463
557
// / `SILModule`: original function name, parameter indices, result indices, and
464
558
// / derivative generic signature.
0 commit comments