@@ -2187,7 +2187,8 @@ class ValueDecl : public Decl {
21872187 // / implementations for the requirements of a public protocol, even when
21882188 // / the default implementations are not visible to name lookup.
21892189 bool isAccessibleFrom (const DeclContext *DC,
2190- bool forConformance = false ) const ;
2190+ bool forConformance = false ,
2191+ bool includeInlineable = false ) const ;
21912192
21922193 // / Returns whether this declaration should be treated as \c open from
21932194 // / \p useDC. This is very similar to #getFormalAccess, but takes
@@ -3741,62 +3742,79 @@ class ClassDecl final : public NominalTypeDecl {
37413742 }
37423743};
37433744
3745+ // / A convenience wrapper around the \c SelfReferencePosition::Kind enum.
3746+ struct SelfReferencePosition final {
3747+ enum Kind : uint8_t { None, Covariant, Contravariant, Invariant };
37443748
3745- // / Describes whether a requirement refers to 'Self', for use in the
3746- // / is-inheritable and is-available-existential checks.
3747- struct SelfReferenceKind {
3748- bool result;
3749- bool parameter;
3750- bool requirement;
3751- bool other;
3749+ private:
3750+ Kind kind;
37523751
3753- // / The type does not refer to 'Self' at all.
3754- static SelfReferenceKind None () {
3755- return SelfReferenceKind (false , false , false , false );
3752+ public:
3753+ SelfReferencePosition (Kind kind) : kind(kind) {}
3754+
3755+ SelfReferencePosition flipped () const {
3756+ switch (kind) {
3757+ case None:
3758+ case Invariant:
3759+ return *this ;
3760+ case Covariant:
3761+ return Contravariant;
3762+ case Contravariant:
3763+ return Covariant;
3764+ }
37563765 }
37573766
3758- // / The type refers to 'Self', but only as the type of a property or
3759- // / the result type of a method/subscript.
3760- static SelfReferenceKind Result () {
3761- return SelfReferenceKind (true , false , false , false );
3762- }
3767+ explicit operator bool () const { return kind > None; }
37633768
3764- // / The type refers to 'Self', but only as the parameter type
3765- // / of a method/subscript.
3766- static SelfReferenceKind Parameter () {
3767- return SelfReferenceKind (false , true , false , false );
3768- }
3769+ operator Kind () const { return kind; }
3770+ };
37693771
3770- // / The type refers to 'Self' within a same-type requiement.
3771- static SelfReferenceKind Requirement () {
3772- return SelfReferenceKind (false , false , true , false );
3773- }
3772+ // / Describes the least favorable positions at which a requirement refers
3773+ // / to 'Self' in terms of variance, for use in the is-inheritable and
3774+ // / is-available-existential checks.
3775+ struct SelfReferenceInfo final {
3776+ using Position = SelfReferencePosition;
3777+
3778+ bool hasCovariantSelfResult;
3779+ Position selfRef;
3780+ Position assocTypeRef;
37743781
3775- // / The type refers to 'Self' in a position that is invariant.
3776- static SelfReferenceKind Other () {
3777- return SelfReferenceKind (false , false , false , true );
3782+ // / A reference to 'Self'.
3783+ static SelfReferenceInfo forSelfRef (Position position) {
3784+ assert (position);
3785+ return SelfReferenceInfo (false , position, Position::None);
37783786 }
37793787
3780- SelfReferenceKind flip () const {
3781- return SelfReferenceKind (parameter, result, requirement, other);
3788+ // / A reference to 'Self' through an associated type.
3789+ static SelfReferenceInfo forAssocTypeRef (Position position) {
3790+ assert (position);
3791+ return SelfReferenceInfo (false , Position::None, position);
37823792 }
37833793
3784- SelfReferenceKind operator |=(SelfReferenceKind kind) {
3785- result |= kind.result ;
3786- requirement |= kind.requirement ;
3787- parameter |= kind.parameter ;
3788- other |= kind.other ;
3794+ SelfReferenceInfo operator |=(const SelfReferenceInfo &pos) {
3795+ hasCovariantSelfResult |= pos.hasCovariantSelfResult ;
3796+ if (pos.selfRef > selfRef) {
3797+ selfRef = pos.selfRef ;
3798+ }
3799+ if (pos.assocTypeRef > assocTypeRef) {
3800+ assocTypeRef = pos.assocTypeRef ;
3801+ }
37893802 return *this ;
37903803 }
37913804
3792- operator bool () const {
3793- return result || parameter || requirement || other ;
3805+ explicit operator bool () const {
3806+ return hasCovariantSelfResult || selfRef || assocTypeRef ;
37943807 }
37953808
3809+ SelfReferenceInfo ()
3810+ : hasCovariantSelfResult(false ), selfRef(Position::None),
3811+ assocTypeRef (Position::None) {}
3812+
37963813private:
3797- SelfReferenceKind (bool result, bool parameter, bool requirement, bool other)
3798- : result(result), parameter(parameter), requirement(requirement),
3799- other (other) { }
3814+ SelfReferenceInfo (bool hasCovariantSelfResult, Position selfRef,
3815+ Position assocTypeRef)
3816+ : hasCovariantSelfResult(hasCovariantSelfResult), selfRef(selfRef),
3817+ assocTypeRef(assocTypeRef) {}
38003818};
38013819
38023820// / The set of known protocols for which derived conformances are supported.
@@ -3978,15 +3996,12 @@ class ProtocolDecl final : public NominalTypeDecl {
39783996
39793997 // / Find direct Self references within the given requirement.
39803998 // /
3981- // / \param allowCovariantParameters If true, 'Self' is assumed to be
3982- // / covariant anywhere; otherwise, only in the return type of the top-level
3983- // / function type.
3984- // /
3985- // / \param skipAssocTypes If true, associated types of 'Self' are ignored;
3986- // / otherwise, they count as an 'other' usage of 'Self'.
3987- SelfReferenceKind findProtocolSelfReferences (const ValueDecl *decl,
3988- bool allowCovariantParameters,
3989- bool skipAssocTypes) const ;
3999+ // / \param treatNonResultCovariantSelfAsInvariant If true, 'Self' is only
4000+ // / assumed to be covariant in a top-level non-function type, or in the
4001+ // / eventual result type of a top-level function type.
4002+ SelfReferenceInfo
4003+ findProtocolSelfReferences (const ValueDecl *decl,
4004+ bool treatNonResultCovariantSelfAsInvariant) const ;
39904005
39914006 // / Determine whether we are allowed to refer to an existential type
39924007 // / conforming to this protocol. This is only permitted if the type of
0 commit comments