@@ -22,52 +22,80 @@ namespace swift {
2222class CanGenericSignature ;
2323class GenericTypeParamType ;
2424
25- // / Describes the least favorable positions at which a requirement refers
26- // / to a given generic parameter in terms of variance, for use in the
27- // / is-inheritable and is-available-existential checks.
25+ // / Stores the variance positions at which a type references a specific
26+ // / generic parameter.
2827class GenericParameterReferenceInfo final {
29- using OptionalTypePosition = OptionalEnum<decltype (TypePosition::Covariant)>;
28+ static constexpr unsigned NumTypePositionBits = 4 ;
29+ static_assert (NumTypePositions <= NumTypePositionBits,
30+ " Not enough bits to store all cases" );
31+
32+ uint8_t DirectRefs : NumTypePositionBits;
33+ uint8_t DepMemberTyRefs : NumTypePositionBits;
34+
35+ // / Whether there is a reference to the generic parameter at hand in covariant
36+ // / result type position. This position is the uncurried interface type of a
37+ // / declaration, stipped of any optionality. For example, this is true for
38+ // / 'Self' in 'func foo(Int) -> () -> Self?'.
39+ bool HasCovariantGenericParamResult;
40+
41+ GenericParameterReferenceInfo (uint8_t DirectRefs, uint8_t DepMemberTyRefs,
42+ bool HasCovariantGenericParamResult)
43+ : DirectRefs(DirectRefs), DepMemberTyRefs(DepMemberTyRefs),
44+ HasCovariantGenericParamResult (HasCovariantGenericParamResult) {}
3045
3146public:
32- // / Whether the uncurried interface type of the declaration, stripped of any
33- // / optionality, is a direct reference to the generic parameter at hand. For
34- // / example, "func foo(x: Int) -> () -> Self?" has a covariant 'Self' result.
35- bool hasCovariantSelfResult;
47+ GenericParameterReferenceInfo ()
48+ : GenericParameterReferenceInfo(0 , 0 , false ) {}
3649
37- OptionalTypePosition selfRef;
38- OptionalTypePosition assocTypeRef;
50+ // / A direct reference to the generic parameter.
51+ static GenericParameterReferenceInfo forDirectRef (TypePosition pos) {
52+ return GenericParameterReferenceInfo (pos, 0 , false );
53+ }
3954
40- // / A reference to 'Self'.
41- static GenericParameterReferenceInfo forSelfRef (TypePosition position) {
42- return GenericParameterReferenceInfo (false , position, std::nullopt );
55+ // / A direct reference to the generic parameter in covariant result type
56+ // / position.
57+ static GenericParameterReferenceInfo forCovariantGenericParamResult () {
58+ return GenericParameterReferenceInfo (TypePosition::Covariant, 0 , true );
4359 }
4460
45- // / A reference to the generic parameter in covariant result position .
46- static GenericParameterReferenceInfo forCovariantResult () {
47- return GenericParameterReferenceInfo ( true , TypePosition::Covariant,
48- std:: nullopt );
61+ // / A reference to a dependent member type rooted on the generic parameter .
62+ static GenericParameterReferenceInfo
63+ forDependentMemberTypeRef ( TypePosition pos) {
64+ return GenericParameterReferenceInfo ( 0 , pos, false );
4965 }
5066
51- // / A reference to 'Self' through an associated type.
52- static GenericParameterReferenceInfo forAssocTypeRef (TypePosition position) {
53- return GenericParameterReferenceInfo (false , std::nullopt , position);
67+ bool hasDirectRef (std::optional<TypePosition> pos = std::nullopt ) const {
68+ if (!pos) {
69+ return DirectRefs;
70+ }
71+
72+ return DirectRefs & pos.value ();
5473 }
5574
56- GenericParameterReferenceInfo &operator |=(const GenericParameterReferenceInfo &other);
75+ bool hasDependentMemberTypeRef (
76+ std::optional<TypePosition> pos = std::nullopt ) const {
77+ if (!pos) {
78+ return DepMemberTyRefs;
79+ }
5780
58- explicit operator bool () const {
59- return hasCovariantSelfResult || selfRef || assocTypeRef;
81+ return DepMemberTyRefs & pos.value ();
6082 }
6183
62- GenericParameterReferenceInfo ()
63- : hasCovariantSelfResult(false ), selfRef(std::nullopt ),
64- assocTypeRef (std::nullopt ) {}
65-
66- private:
67- GenericParameterReferenceInfo (bool hasCovariantSelfResult, OptionalTypePosition selfRef,
68- OptionalTypePosition assocTypeRef)
69- : hasCovariantSelfResult(hasCovariantSelfResult), selfRef(selfRef),
70- assocTypeRef(assocTypeRef) {}
84+ bool hasNonCovariantRef () const {
85+ const uint8_t notCovariant = ~TypePosition::Covariant;
86+ return (DirectRefs & notCovariant) || (DepMemberTyRefs & notCovariant);
87+ }
88+
89+ bool hasCovariantGenericParamResult () const {
90+ return HasCovariantGenericParamResult;
91+ }
92+
93+ GenericParameterReferenceInfo &
94+ operator |=(const GenericParameterReferenceInfo &other);
95+
96+ explicit operator bool () const {
97+ return hasDirectRef () || hasDependentMemberTypeRef ();
98+ }
7199};
72100
73101// / Find references to the given generic parameter in the type signature of the
@@ -138,4 +166,4 @@ Type typeEraseOpenedArchetypesFromEnvironment(Type type,
138166
139167} // end namespace swift
140168
141- #endif
169+ #endif
0 commit comments