@@ -2187,7 +2187,8 @@ class ValueDecl : public Decl {
2187
2187
// / implementations for the requirements of a public protocol, even when
2188
2188
// / the default implementations are not visible to name lookup.
2189
2189
bool isAccessibleFrom (const DeclContext *DC,
2190
- bool forConformance = false ) const ;
2190
+ bool forConformance = false ,
2191
+ bool includeInlineable = false ) const ;
2191
2192
2192
2193
// / Returns whether this declaration should be treated as \c open from
2193
2194
// / \p useDC. This is very similar to #getFormalAccess, but takes
@@ -3741,62 +3742,79 @@ class ClassDecl final : public NominalTypeDecl {
3741
3742
}
3742
3743
};
3743
3744
3745
+ // / A convenience wrapper around the \c SelfReferencePosition::Kind enum.
3746
+ struct SelfReferencePosition final {
3747
+ enum Kind : uint8_t { None, Covariant, Contravariant, Invariant };
3744
3748
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;
3752
3751
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
+ }
3756
3765
}
3757
3766
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; }
3763
3768
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
+ };
3769
3771
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;
3774
3781
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);
3778
3786
}
3779
3787
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);
3782
3792
}
3783
3793
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
+ }
3789
3802
return *this ;
3790
3803
}
3791
3804
3792
- operator bool () const {
3793
- return result || parameter || requirement || other ;
3805
+ explicit operator bool () const {
3806
+ return hasCovariantSelfResult || selfRef || assocTypeRef ;
3794
3807
}
3795
3808
3809
+ SelfReferenceInfo ()
3810
+ : hasCovariantSelfResult(false ), selfRef(Position::None),
3811
+ assocTypeRef (Position::None) {}
3812
+
3796
3813
private:
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) {}
3800
3818
};
3801
3819
3802
3820
// / The set of known protocols for which derived conformances are supported.
@@ -3978,15 +3996,12 @@ class ProtocolDecl final : public NominalTypeDecl {
3978
3996
3979
3997
// / Find direct Self references within the given requirement.
3980
3998
// /
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 ;
3990
4005
3991
4006
// / Determine whether we are allowed to refer to an existential type
3992
4007
// / conforming to this protocol. This is only permitted if the type of
0 commit comments