Skip to content

Commit 51abd3d

Browse files
committed
Prevent opening existentials when the corresponding parameter is variant
Ensure that we only open existentials in an argument when the corresponding parameter's type is a generic parameter that is only used in covariant positions, because either invariant or contravariant uses mean that we won't be able to type-erase other uses of that parameter. This mirrors the requirement placed when opening existentials as a member of protocol type.
1 parent 6c03882 commit 51abd3d

File tree

4 files changed

+255
-99
lines changed

4 files changed

+255
-99
lines changed

include/swift/AST/Decl.h

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,9 +2159,9 @@ class PoundDiagnosticDecl : public Decl {
21592159
class OpaqueTypeDecl;
21602160

21612161
/// Describes the least favorable positions at which a requirement refers
2162-
/// to 'Self' in terms of variance, for use in the is-inheritable and
2163-
/// is-available-existential checks.
2164-
class SelfReferenceInfo final {
2162+
/// to a given generic parameter in terms of variance, for use in the
2163+
/// is-inheritable and is-available-existential checks.
2164+
class GenericParameterReferenceInfo final {
21652165
using OptionalTypePosition = OptionalEnum<decltype(TypePosition::Covariant)>;
21662166

21672167
public:
@@ -2171,27 +2171,27 @@ class SelfReferenceInfo final {
21712171
OptionalTypePosition assocTypeRef;
21722172

21732173
/// A reference to 'Self'.
2174-
static SelfReferenceInfo forSelfRef(TypePosition position) {
2175-
return SelfReferenceInfo(false, position, llvm::None);
2174+
static GenericParameterReferenceInfo forSelfRef(TypePosition position) {
2175+
return GenericParameterReferenceInfo(false, position, llvm::None);
21762176
}
21772177

21782178
/// A reference to 'Self' through an associated type.
2179-
static SelfReferenceInfo forAssocTypeRef(TypePosition position) {
2180-
return SelfReferenceInfo(false, llvm::None, position);
2179+
static GenericParameterReferenceInfo forAssocTypeRef(TypePosition position) {
2180+
return GenericParameterReferenceInfo(false, llvm::None, position);
21812181
}
21822182

2183-
SelfReferenceInfo &operator|=(const SelfReferenceInfo &other);
2183+
GenericParameterReferenceInfo &operator|=(const GenericParameterReferenceInfo &other);
21842184

21852185
explicit operator bool() const {
21862186
return hasCovariantSelfResult || selfRef || assocTypeRef;
21872187
}
21882188

2189-
SelfReferenceInfo()
2189+
GenericParameterReferenceInfo()
21902190
: hasCovariantSelfResult(false), selfRef(llvm::None),
21912191
assocTypeRef(llvm::None) {}
21922192

21932193
private:
2194-
SelfReferenceInfo(bool hasCovariantSelfResult, OptionalTypePosition selfRef,
2194+
GenericParameterReferenceInfo(bool hasCovariantSelfResult, OptionalTypePosition selfRef,
21952195
OptionalTypePosition assocTypeRef)
21962196
: hasCovariantSelfResult(hasCovariantSelfResult), selfRef(selfRef),
21972197
assocTypeRef(assocTypeRef) {}
@@ -2682,7 +2682,7 @@ class ValueDecl : public Decl {
26822682
/// is considered covariant only when it appears as the immediate type of a
26832683
/// property, or the uncurried result type of a method/subscript, e.g.
26842684
/// '() -> () -> Self'.
2685-
SelfReferenceInfo findExistentialSelfReferences(
2685+
GenericParameterReferenceInfo findExistentialSelfReferences(
26862686
Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const;
26872687
};
26882688

@@ -7800,6 +7800,14 @@ class MissingMemberDecl : public Decl {
78007800
}
78017801
};
78027802

7803+
/// Find references to the given generic paramaeter in the generic signature
7804+
/// and the type of the given value.
7805+
GenericParameterReferenceInfo findGenericParameterReferences(
7806+
const ValueDecl *value,
7807+
CanGenericSignature sig, GenericTypeParamType *genericParam,
7808+
bool treatNonResultCovarianceAsInvariant,
7809+
Optional<unsigned> skipParamIndex);
7810+
78037811
inline bool AbstractStorageDecl::isSettable(const DeclContext *UseDC,
78047812
const DeclRefExpr *base) const {
78057813
if (auto vd = dyn_cast<VarDecl>(this))

0 commit comments

Comments
 (0)