@@ -35,6 +35,7 @@ class AnyFunctionType;
3535class SourceFile ;
3636class SILFunctionType ;
3737class TupleType ;
38+ class VarDecl ;
3839
3940// / A function type differentiability kind.
4041enum class DifferentiabilityKind : uint8_t {
@@ -459,6 +460,99 @@ class DerivativeFunctionTypeError
459460 }
460461};
461462
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+
462556// / The key type used for uniquing `SILDifferentiabilityWitness` in
463557// / `SILModule`: original function name, parameter indices, result indices, and
464558// / derivative generic signature.
0 commit comments