@@ -2157,6 +2157,45 @@ class PoundDiagnosticDecl : public Decl {
21572157
21582158class OpaqueTypeDecl ;
21592159
2160+ // / Describes the least favorable positions at which a requirement refers
2161+ // / to 'Self' in terms of variance, for use in the is-inheritable and
2162+ // / is-available-existential checks.
2163+ class SelfReferenceInfo final {
2164+ using OptionalTypePosition = OptionalEnum<decltype (TypePosition::Covariant)>;
2165+
2166+ public:
2167+ bool hasCovariantSelfResult;
2168+
2169+ OptionalTypePosition selfRef;
2170+ OptionalTypePosition assocTypeRef;
2171+
2172+ // / A reference to 'Self'.
2173+ static SelfReferenceInfo forSelfRef (TypePosition position) {
2174+ return SelfReferenceInfo (false , position, llvm::None);
2175+ }
2176+
2177+ // / A reference to 'Self' through an associated type.
2178+ static SelfReferenceInfo forAssocTypeRef (TypePosition position) {
2179+ return SelfReferenceInfo (false , llvm::None, position);
2180+ }
2181+
2182+ SelfReferenceInfo &operator |=(const SelfReferenceInfo &other);
2183+
2184+ explicit operator bool () const {
2185+ return hasCovariantSelfResult || selfRef || assocTypeRef;
2186+ }
2187+
2188+ SelfReferenceInfo ()
2189+ : hasCovariantSelfResult(false ), selfRef(llvm::None),
2190+ assocTypeRef (llvm::None) {}
2191+
2192+ private:
2193+ SelfReferenceInfo (bool hasCovariantSelfResult, OptionalTypePosition selfRef,
2194+ OptionalTypePosition assocTypeRef)
2195+ : hasCovariantSelfResult(hasCovariantSelfResult), selfRef(selfRef),
2196+ assocTypeRef(assocTypeRef) {}
2197+ };
2198+
21602199// / ValueDecl - All named decls that are values in the language. These can
21612200// / have a type, etc.
21622201class ValueDecl : public Decl {
@@ -2634,6 +2673,16 @@ class ValueDecl : public Decl {
26342673 // / @_dynamicReplacement(for: ...), compute the original declaration
26352674 // / that this declaration dynamically replaces.
26362675 ValueDecl *getDynamicallyReplacedDecl () const ;
2676+
2677+ // / Report 'Self' references within the type of this declaration as a
2678+ // / member of the given existential base type.
2679+ // /
2680+ // / \param treatNonResultCovariantSelfAsInvariant If true, 'Self' or 'Self?'
2681+ // / is considered covariant only when it appears as the immediate type of a
2682+ // / property, or the uncurried result type of a method/subscript, e.g.
2683+ // / '() -> () -> Self'.
2684+ SelfReferenceInfo findExistentialSelfReferences (
2685+ Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const ;
26372686};
26382687
26392688// / This is a common base class for declarations which declare a type.
@@ -4212,82 +4261,6 @@ class ClassDecl final : public NominalTypeDecl {
42124261 bool isForeignReferenceType ();
42134262};
42144263
4215- // / A convenience wrapper around the \c SelfReferencePosition::Kind enum.
4216- struct SelfReferencePosition final {
4217- enum Kind : uint8_t { None, Covariant, Contravariant, Invariant };
4218-
4219- private:
4220- Kind kind;
4221-
4222- public:
4223- SelfReferencePosition (Kind kind) : kind(kind) {}
4224-
4225- SelfReferencePosition flipped () const {
4226- switch (kind) {
4227- case None:
4228- case Invariant:
4229- return *this ;
4230- case Covariant:
4231- return Contravariant;
4232- case Contravariant:
4233- return Covariant;
4234- }
4235- llvm_unreachable (" unhandled self reference position!" );
4236- }
4237-
4238- explicit operator bool () const { return kind > None; }
4239-
4240- operator Kind () const { return kind; }
4241- };
4242-
4243- // / Describes the least favorable positions at which a requirement refers
4244- // / to 'Self' in terms of variance, for use in the is-inheritable and
4245- // / is-available-existential checks.
4246- struct SelfReferenceInfo final {
4247- using Position = SelfReferencePosition;
4248-
4249- bool hasCovariantSelfResult;
4250- Position selfRef;
4251- Position assocTypeRef;
4252-
4253- // / A reference to 'Self'.
4254- static SelfReferenceInfo forSelfRef (Position position) {
4255- assert (position);
4256- return SelfReferenceInfo (false , position, Position::None);
4257- }
4258-
4259- // / A reference to 'Self' through an associated type.
4260- static SelfReferenceInfo forAssocTypeRef (Position position) {
4261- assert (position);
4262- return SelfReferenceInfo (false , Position::None, position);
4263- }
4264-
4265- SelfReferenceInfo operator |=(const SelfReferenceInfo &pos) {
4266- hasCovariantSelfResult |= pos.hasCovariantSelfResult ;
4267- if (pos.selfRef > selfRef) {
4268- selfRef = pos.selfRef ;
4269- }
4270- if (pos.assocTypeRef > assocTypeRef) {
4271- assocTypeRef = pos.assocTypeRef ;
4272- }
4273- return *this ;
4274- }
4275-
4276- explicit operator bool () const {
4277- return hasCovariantSelfResult || selfRef || assocTypeRef;
4278- }
4279-
4280- SelfReferenceInfo ()
4281- : hasCovariantSelfResult(false ), selfRef(Position::None),
4282- assocTypeRef (Position::None) {}
4283-
4284- private:
4285- SelfReferenceInfo (bool hasCovariantSelfResult, Position selfRef,
4286- Position assocTypeRef)
4287- : hasCovariantSelfResult(hasCovariantSelfResult), selfRef(selfRef),
4288- assocTypeRef(assocTypeRef) {}
4289- };
4290-
42914264// / The set of known protocols for which derived conformances are supported.
42924265enum class KnownDerivableProtocolKind : uint8_t {
42934266 RawRepresentable,
@@ -4481,21 +4454,6 @@ class ProtocolDecl final : public NominalTypeDecl {
44814454 // / Does this protocol require a self-conformance witness table?
44824455 bool requiresSelfConformanceWitnessTable () const ;
44834456
4484- // / Find direct Self references within the given requirement.
4485- // /
4486- // / \param treatNonResultCovariantSelfAsInvariant If true, 'Self' is only
4487- // / assumed to be covariant in a top-level non-function type, or in the
4488- // / eventual result type of a top-level function type.
4489- SelfReferenceInfo
4490- findProtocolSelfReferences (const ValueDecl *decl,
4491- bool treatNonResultCovariantSelfAsInvariant) const ;
4492-
4493- // / Determine whether we are allowed to refer to an existential type
4494- // / conforming to this protocol. This is only permitted if the type of
4495- // / the member does not contain any associated types, and does not
4496- // / contain 'Self' in 'parameter' or 'other' position.
4497- bool isAvailableInExistential (const ValueDecl *decl) const ;
4498-
44994457 // / Determine whether an existential type must be explicitly prefixed
45004458 // / with \c any. \c any is required if any of the members contain
45014459 // / an associated type, or if \c Self appears in non-covariant position.
0 commit comments