Skip to content

Commit 3206f5a

Browse files
committed
[NFC] Preemptively relocate ProtocolDecl::isAvailableInExistential() and co.
1 parent b6a4923 commit 3206f5a

File tree

7 files changed

+321
-314
lines changed

7 files changed

+321
-314
lines changed

include/swift/AST/Decl.h

Lines changed: 85 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,82 @@ class PoundDiagnosticDecl : public Decl {
21572157

21582158
class OpaqueTypeDecl;
21592159

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+
21602236
/// ValueDecl - All named decls that are values in the language. These can
21612237
/// have a type, etc.
21622238
class ValueDecl : public Decl {
@@ -2634,6 +2710,15 @@ class ValueDecl : public Decl {
26342710
/// @_dynamicReplacement(for: ...), compute the original declaration
26352711
/// that this declaration dynamically replaces.
26362712
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;
26372722
};
26382723

26392724
/// This is a common base class for declarations which declare a type.
@@ -4212,82 +4297,6 @@ class ClassDecl final : public NominalTypeDecl {
42124297
bool isForeignReferenceType();
42134298
};
42144299

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-
42914300
/// The set of known protocols for which derived conformances are supported.
42924301
enum class KnownDerivableProtocolKind : uint8_t {
42934302
RawRepresentable,
@@ -4481,21 +4490,6 @@ class ProtocolDecl final : public NominalTypeDecl {
44814490
/// Does this protocol require a self-conformance witness table?
44824491
bool requiresSelfConformanceWitnessTable() const;
44834492

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-
44994493
/// Determine whether an existential type must be explicitly prefixed
45004494
/// with \c any. \c any is required if any of the members contain
45014495
/// an associated type, or if \c Self appears in non-covariant position.

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,6 +5296,13 @@ class ConstraintSystem {
52965296
/// in (if any) has a result builder applied to its body.
52975297
bool isInResultBuilderContext(ClosureExpr *closure) const;
52985298

5299+
/// Determine whether we are allowed to refer to an existential type
5300+
/// conforming to the given protocol. This is only permitted if the type of
5301+
/// the member does not contain any associated types, and does not
5302+
/// contain 'Self' in 'parameter' or 'other' position.
5303+
bool isAvailableInExistential(const ProtocolDecl *proto,
5304+
const ValueDecl *member) const;
5305+
52995306
SWIFT_DEBUG_DUMP;
53005307
SWIFT_DEBUG_DUMPER(dump(Expr *));
53015308

0 commit comments

Comments
 (0)