@@ -22,52 +22,80 @@ namespace swift {
22
22
class CanGenericSignature ;
23
23
class GenericTypeParamType ;
24
24
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.
28
27
class 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) {}
30
45
31
46
public:
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 ) {}
36
49
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
+ }
39
54
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 );
43
59
}
44
60
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 );
49
65
}
50
66
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 ();
54
73
}
55
74
56
- GenericParameterReferenceInfo &operator |=(const GenericParameterReferenceInfo &other);
75
+ bool hasDependentMemberTypeRef (
76
+ std::optional<TypePosition> pos = std::nullopt) const {
77
+ if (!pos) {
78
+ return DepMemberTyRefs;
79
+ }
57
80
58
- explicit operator bool () const {
59
- return hasCovariantSelfResult || selfRef || assocTypeRef;
81
+ return DepMemberTyRefs & pos.value ();
60
82
}
61
83
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
+ }
71
99
};
72
100
73
101
// / Find references to the given generic parameter in the type signature of the
@@ -138,4 +166,4 @@ Type typeEraseOpenedArchetypesFromEnvironment(Type type,
138
166
139
167
} // end namespace swift
140
168
141
- #endif
169
+ #endif
0 commit comments