Skip to content

Sema: Consolidate logic for opening existentials in OpenedExistentials.cpp #76263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 0 additions & 62 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2753,54 +2753,6 @@ class PoundDiagnosticDecl : public Decl {

class OpaqueTypeDecl;

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

public:
/// Whether the uncurried interface type of the declaration, stripped of any
/// optionality, is a direct reference to the generic parameter at hand. For
/// example, "func foo(x: Int) -> () -> Self?" has a covariant 'Self' result.
bool hasCovariantSelfResult;

OptionalTypePosition selfRef;
OptionalTypePosition assocTypeRef;

/// A reference to 'Self'.
static GenericParameterReferenceInfo forSelfRef(TypePosition position) {
return GenericParameterReferenceInfo(false, position, std::nullopt);
}

/// A reference to the generic parameter in covariant result position.
static GenericParameterReferenceInfo forCovariantResult() {
return GenericParameterReferenceInfo(true, TypePosition::Covariant,
std::nullopt);
}

/// A reference to 'Self' through an associated type.
static GenericParameterReferenceInfo forAssocTypeRef(TypePosition position) {
return GenericParameterReferenceInfo(false, std::nullopt, position);
}

GenericParameterReferenceInfo &operator|=(const GenericParameterReferenceInfo &other);

explicit operator bool() const {
return hasCovariantSelfResult || selfRef || assocTypeRef;
}

GenericParameterReferenceInfo()
: hasCovariantSelfResult(false), selfRef(std::nullopt),
assocTypeRef(std::nullopt) {}

private:
GenericParameterReferenceInfo(bool hasCovariantSelfResult, OptionalTypePosition selfRef,
OptionalTypePosition assocTypeRef)
: hasCovariantSelfResult(hasCovariantSelfResult), selfRef(selfRef),
assocTypeRef(assocTypeRef) {}
};

/// ValueDecl - All named decls that are values in the language. These can
/// have a type, etc.
class ValueDecl : public Decl {
Expand Down Expand Up @@ -3334,9 +3286,6 @@ class ValueDecl : public Decl {
/// @_dynamicReplacement(for: ...), compute the original declaration
/// that this declaration dynamically replaces.
ValueDecl *getDynamicallyReplacedDecl() const;

/// Find references to 'Self' in the type signature of this declaration.
GenericParameterReferenceInfo findExistentialSelfReferences() const;
};

/// This is a common base class for declarations which declare a type.
Expand Down Expand Up @@ -9517,17 +9466,6 @@ class MacroExpansionDecl : public Decl, public FreestandingMacroExpansion {
}
};

/// Find references to the given generic parameter in the type signature of the
/// given declaration using the given generic signature.
///
/// \param skipParamIndex If the value is a function or subscript declaration,
/// specifies the index of the parameter that shall be skipped.
GenericParameterReferenceInfo
findGenericParameterReferences(const ValueDecl *value, CanGenericSignature sig,
GenericTypeParamType *origParam,
GenericTypeParamType *openedParam,
std::optional<unsigned> skipParamIndex);

inline void
AbstractStorageDecl::overwriteSetterAccess(AccessLevel accessLevel) {
Accessors.setInt(accessLevel);
Expand Down
9 changes: 9 additions & 0 deletions include/swift/AST/SubstitutionMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ class SubstitutionMap {
ArrayRef<Type> replacementTypes,
LookupConformanceFn lookupConformance);

/// Build a substitution map from the substitutions represented by
/// the given in-flight substitution.
///
/// This function should generally only be used by the substitution
/// subsystem.
static SubstitutionMap get(GenericSignature genericSig,
ArrayRef<Type> replacementTypes,
InFlightSubstitution &IFS);

/// Build a substitution map from the substitutions represented by
/// the given in-flight substitution.
///
Expand Down
4 changes: 1 addition & 3 deletions include/swift/AST/TypeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,9 +998,7 @@ case TypeKind::Id:
return subs;

auto sig = subs.getGenericSignature();
return SubstitutionMap::get(sig,
QueryReplacementTypeArray{sig, newSubs},
LookUpConformanceInModule());
return SubstitutionMap::get(sig, newSubs, LookUpConformanceInModule());
}

CanType transformSILField(CanType fieldTy, TypePosition pos) {
Expand Down
5 changes: 5 additions & 0 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ struct SubstitutionMapWithLocalArchetypes {
ProtocolDecl *proto) {
if (isa<LocalArchetypeType>(origType))
return swift::lookupConformance(substType, proto);

if (isa<PrimaryArchetypeType>(origType) ||
isa<PackArchetypeType>(origType))
origType = origType->mapTypeOutOfContext()->getCanonicalType();

if (SubsMap)
return SubsMap->lookupConformance(origType, proto);

Expand Down
21 changes: 0 additions & 21 deletions include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -5697,13 +5697,6 @@ class ConstraintSystem {
/// part of the constraint system.
void forEachExpr(Expr *expr, llvm::function_ref<Expr *(Expr *)> callback);

/// Determine whether referencing the given member on the
/// given existential base type is supported. This is the case only if the
/// type of the member, spelled in the context of \p baseTy, does not contain
/// 'Self' or 'Self'-rooted dependent member types in non-covariant position.
bool isMemberAvailableOnExistential(Type baseTy,
const ValueDecl *member) const;

/// Attempts to infer a capability of a key path (i.e. whether it
/// is read-only, writable, etc.) based on the referenced members.
///
Expand Down Expand Up @@ -5961,20 +5954,6 @@ std::optional<MatchCallArgumentResult> matchCallArguments(
/// subscript, etc.), find the underlying target expression.
Expr *getArgumentLabelTargetExpr(Expr *fn);

/// Given a type that includes an existential type that has been opened to
/// the given type variable, replace the opened type variable and its member
/// types with their upper bounds.
Type typeEraseOpenedExistentialReference(Type type, Type existentialBaseType,
TypeVariableType *openedTypeVar,
TypePosition outermostPosition);


/// Given a type that includes opened existential archetypes derived from
/// the given generic environment, replace the archetypes with their upper
/// bounds.
Type typeEraseOpenedArchetypesFromEnvironment(Type type,
GenericEnvironment *env);

/// Returns true if a reference to a member on a given base type will apply
/// its curried self parameter, assuming it has one.
///
Expand Down
Loading