@@ -2157,6 +2157,82 @@ class PoundDiagnosticDecl : public Decl {
2157
2157
2158
2158
class OpaqueTypeDecl ;
2159
2159
2160
+ // / A convenience wrapper around the \c SelfReferencePosition::Kind enum.
2161
+ struct SelfReferencePosition final {
2162
+ enum Kind : uint8_t { None, Covariant, Contravariant, Invariant };
2163
+
2164
+ private:
2165
+ Kind kind;
2166
+
2167
+ public:
2168
+ SelfReferencePosition (Kind kind) : kind(kind) {}
2169
+
2170
+ SelfReferencePosition flipped () const {
2171
+ switch (kind) {
2172
+ case None:
2173
+ case Invariant:
2174
+ return *this ;
2175
+ case Covariant:
2176
+ return Contravariant;
2177
+ case Contravariant:
2178
+ return Covariant;
2179
+ }
2180
+ llvm_unreachable (" unhandled self reference position!" );
2181
+ }
2182
+
2183
+ explicit operator bool () const { return kind > None; }
2184
+
2185
+ operator Kind () const { return kind; }
2186
+ };
2187
+
2188
+ // / Describes the least favorable positions at which a protocol member refers
2189
+ // / to 'Self' in terms of variance. Used in the is-inheritable and
2190
+ // / is-available-in-existential checks.
2191
+ struct SelfReferenceInfo final {
2192
+ using Position = SelfReferencePosition;
2193
+
2194
+ bool hasCovariantSelfResult;
2195
+ Position selfRef;
2196
+ Position assocTypeRef;
2197
+
2198
+ // / A reference to 'Self'.
2199
+ static SelfReferenceInfo forSelfRef (Position position) {
2200
+ assert (position);
2201
+ return SelfReferenceInfo (false , position, Position::None);
2202
+ }
2203
+
2204
+ // / A reference to 'Self' through an associated type.
2205
+ static SelfReferenceInfo forAssocTypeRef (Position position) {
2206
+ assert (position);
2207
+ return SelfReferenceInfo (false , Position::None, position);
2208
+ }
2209
+
2210
+ SelfReferenceInfo operator |=(const SelfReferenceInfo &pos) {
2211
+ hasCovariantSelfResult |= pos.hasCovariantSelfResult ;
2212
+ if (pos.selfRef > selfRef) {
2213
+ selfRef = pos.selfRef ;
2214
+ }
2215
+ if (pos.assocTypeRef > assocTypeRef) {
2216
+ assocTypeRef = pos.assocTypeRef ;
2217
+ }
2218
+ return *this ;
2219
+ }
2220
+
2221
+ explicit operator bool () const {
2222
+ return hasCovariantSelfResult || selfRef || assocTypeRef;
2223
+ }
2224
+
2225
+ SelfReferenceInfo ()
2226
+ : hasCovariantSelfResult(false ), selfRef(Position::None),
2227
+ assocTypeRef (Position::None) {}
2228
+
2229
+ private:
2230
+ SelfReferenceInfo (bool hasCovariantSelfResult, Position selfRef,
2231
+ Position assocTypeRef)
2232
+ : hasCovariantSelfResult(hasCovariantSelfResult), selfRef(selfRef),
2233
+ assocTypeRef(assocTypeRef) {}
2234
+ };
2235
+
2160
2236
// / ValueDecl - All named decls that are values in the language. These can
2161
2237
// / have a type, etc.
2162
2238
class ValueDecl : public Decl {
@@ -2634,6 +2710,15 @@ class ValueDecl : public Decl {
2634
2710
// / @_dynamicReplacement(for: ...), compute the original declaration
2635
2711
// / that this declaration dynamically replaces.
2636
2712
ValueDecl *getDynamicallyReplacedDecl () const ;
2713
+
2714
+ // / Report 'Self' references within the type of this protocol member.
2715
+ // /
2716
+ // / \param treatNonResultCovariantSelfAsInvariant If true, 'Self' or 'Self?'
2717
+ // / is considered covariant only when it appears as the immediate type of a
2718
+ // / property, or the uncurried result type of a method/subscript.
2719
+ SelfReferenceInfo
2720
+ findProtocolSelfReferences (const ProtocolDecl *proto,
2721
+ bool treatNonResultCovariantSelfAsInvariant) const ;
2637
2722
};
2638
2723
2639
2724
// / This is a common base class for declarations which declare a type.
@@ -4212,82 +4297,6 @@ class ClassDecl final : public NominalTypeDecl {
4212
4297
bool isForeignReferenceType ();
4213
4298
};
4214
4299
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
-
4291
4300
// / The set of known protocols for which derived conformances are supported.
4292
4301
enum class KnownDerivableProtocolKind : uint8_t {
4293
4302
RawRepresentable,
@@ -4481,21 +4490,6 @@ class ProtocolDecl final : public NominalTypeDecl {
4481
4490
// / Does this protocol require a self-conformance witness table?
4482
4491
bool requiresSelfConformanceWitnessTable () const ;
4483
4492
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
-
4499
4493
// / Determine whether an existential type must be explicitly prefixed
4500
4494
// / with \c any. \c any is required if any of the members contain
4501
4495
// / an associated type, or if \c Self appears in non-covariant position.
0 commit comments