Skip to content

Place Opened Archetypes in their Proper Generic Contexts #41677

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 7 commits into from
Mar 8, 2022
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
13 changes: 11 additions & 2 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1298,8 +1298,17 @@ class ASTContext final {
CanGenericSignature getSingleGenericParameterSignature() const;

/// Retrieve a generic signature with a single type parameter conforming
/// to the given protocol or composition type, like <T: type>.
CanGenericSignature getOpenedArchetypeSignature(Type type);
/// to the given protocol or composition type, like <T: P>.
///
/// The opened archetype may have a different set of conformances from the
/// corresponding existential. The opened archetype conformances are dictated
/// by the ABI for generic arguments, while the existential value conformances
/// are dictated by their layout (see \c Type::getExistentialLayout()). In
/// particular, the opened archetype signature does not have requirements for
/// conformances inherited from superclass constraints while existential
/// values do.
CanGenericSignature getOpenedArchetypeSignature(Type type,
GenericSignature parentSig);

GenericSignature getOverrideGenericSignature(const ValueDecl *base,
const ValueDecl *derived);
Expand Down
3 changes: 2 additions & 1 deletion include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2693,7 +2693,8 @@ class ValueDecl : public Decl {
/// property, or the uncurried result type of a method/subscript, e.g.
/// '() -> () -> Self'.
GenericParameterReferenceInfo findExistentialSelfReferences(
Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const;
Type baseTy, const DeclContext *useDC,
bool treatNonResultCovariantSelfAsInvariant) const;
};

/// This is a common base class for declarations which declare a type.
Expand Down
24 changes: 23 additions & 1 deletion include/swift/AST/GenericEnvironment.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,29 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
GenericEnvironment *getIncomplete(GenericSignature signature);

/// Create a new generic environment for an opened existential.
static GenericEnvironment *forOpenedExistential(Type existential, UUID uuid);
///
/// This function uses the provided parent signature to construct a new
/// signature suitable for use with an opened archetype. If you have an
/// existing generic signature from e.g. deserialization use
/// \c GenericEnvironment::forOpenedArchetypeSignature instead.
///
/// \param existential The subject existential type
/// \param parentSig The signature of the context where this existential type is being opened
/// \param uuid The unique identifier for this opened existential
static GenericEnvironment *
forOpenedExistential(Type existential, GenericSignature parentSig, UUID uuid);

/// Create a new generic environment for an opened existential.
///
/// It is unlikely you want to use this function.
/// Call \c GenericEnvironment::forOpenedExistential instead.
///
/// \param existential The subject existential type
/// \param signature The signature of the opened archetype
/// \param uuid The unique identifier for this opened existential
static GenericEnvironment *
forOpenedArchetypeSignature(Type existential,
GenericSignature signature, UUID uuid);

/// Create a new generic environment for an opaque type with the given set of
/// outer substitutions.
Expand Down
52 changes: 41 additions & 11 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
/// Canonical protocol composition types are minimized only to a certain
/// degree to preserve ABI compatibility. This routine enables performing
/// slower, but stricter minimization at need (e.g. redeclaration checking).
CanType getMinimalCanonicalType() const;
CanType getMinimalCanonicalType(const DeclContext *useDC) const;

/// Reconstitute type sugar, e.g., for array types, dictionary
/// types, optionals, etc.
Expand Down Expand Up @@ -648,7 +648,8 @@ class alignas(1 << TypeAlignInBits) TypeBase

/// Replace opened archetypes with the given root with their most
/// specific non-dependent upper bounds throughout this type.
Type typeEraseOpenedArchetypesWithRoot(const OpenedArchetypeType *root) const;
Type typeEraseOpenedArchetypesWithRoot(const OpenedArchetypeType *root,
const DeclContext *useDC) const;

/// Given a declaration context, returns a function type with the 'self'
/// type curried as the input if the declaration context describes a type.
Expand Down Expand Up @@ -763,7 +764,8 @@ class alignas(1 << TypeAlignInBits) TypeBase
bool isClassExistentialType();

/// Opens an existential instance or meta-type and returns the opened type.
Type openAnyExistentialType(OpenedArchetypeType *&opened);
Type openAnyExistentialType(OpenedArchetypeType *&opened,
GenericSignature parentSig);

/// Break an existential down into a set of constraints.
ExistentialLayout getExistentialLayout();
Expand Down Expand Up @@ -5189,7 +5191,7 @@ class ProtocolCompositionType final : public TypeBase,
/// Canonical protocol composition types are minimized only to a certain
/// degree to preserve ABI compatibility. This routine enables performing
/// slower, but stricter minimization at need (e.g. redeclaration checking).
CanType getMinimalCanonicalType() const;
CanType getMinimalCanonicalType(const DeclContext *useDC) const;

/// Retrieve the set of members composed to create this type.
///
Expand Down Expand Up @@ -5272,7 +5274,6 @@ class ParameterizedProtocolType final : public TypeBase,
friend TrailingObjects;

ProtocolType *Base;
Type Arg;

public:
/// Retrieve an instance of a protocol composition type with the
Expand Down Expand Up @@ -5745,40 +5746,69 @@ class OpenedArchetypeType final : public ArchetypeType,
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
LayoutConstraint layout);

public:
/// Compute the parameter that serves as the \c Self type for an opened
/// archetype from the given outer generic signature.
///
/// This type is a generic parameter one level deeper
/// than the deepest generic context depth.
static Type getSelfInterfaceTypeFromContext(GenericSignature parentSig,
ASTContext &ctx);

public:
/// Get or create an archetype that represents the opened type
/// of an existential value.
///
/// \param existential The existential type to open.
/// \param parentSig The generic signature of the context opening
/// this existential.
///
/// \param knownID When non-empty, the known ID of the archetype. When empty,
/// a fresh archetype with a unique ID will be opened.
static CanTypeWrapper<OpenedArchetypeType> get(
CanType existential, Optional<UUID> knownID = None);
static CanTypeWrapper<OpenedArchetypeType> get(CanType existential,
GenericSignature parentSig,
Optional<UUID> knownID = None);

/// Get or create an archetype that represents the opened type
/// of an existential value.
///
/// \param existential The existential type to open.
/// \param interfaceType The interface type represented by this archetype.
/// \param parentSig The generic signature of the context opening
/// this existential.
///
/// \param knownID When non-empty, the known ID of the archetype. When empty,
/// a fresh archetype with a unique ID will be opened.
static CanTypeWrapper<OpenedArchetypeType> get(
CanType existential, Type interfaceType, Optional<UUID> knownID = None);
static CanTypeWrapper<OpenedArchetypeType> get(CanType existential,
Type interfaceType,
GenericSignature parentSig,
Optional<UUID> knownID = None);

/// Create a new archetype that represents the opened type
/// of an existential value.
///
/// Use this function when you are unsure of whether the
/// \c existential type is a metatype or an instance type. This function
/// will unwrap any existential metatype containers.
///
/// \param existential The existential type or existential metatype to open.
/// \param interfaceType The interface type represented by this archetype.
static CanType getAny(CanType existential, Type interfaceType);
/// \param parentSig The generic signature of the context opening
/// this existential.
static CanType getAny(CanType existential, Type interfaceType,
GenericSignature parentSig);

/// Create a new archetype that represents the opened type
/// of an existential value.
///
/// Use this function when you are unsure of whether the
/// \c existential type is a metatype or an instance type. This function
/// will unwrap any existential metatype containers.
///
/// \param existential The existential type or existential metatype to open.
static CanType getAny(CanType existential);
/// \param parentSig The generic signature of the context opening
/// this existential.
static CanType getAny(CanType existential, GenericSignature parentSig);

/// Retrieve the ID number of this opened existential.
UUID getOpenedExistentialID() const;
Expand Down
11 changes: 8 additions & 3 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef SWIFT_SIL_SILCLONER_H
#define SWIFT_SIL_SILCLONER_H

#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/SIL/BasicBlockUtils.h"
#include "swift/SIL/DebugUtils.h"
Expand Down Expand Up @@ -251,10 +252,14 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
void remapRootOpenedType(CanOpenedArchetypeType archetypeTy) {
assert(archetypeTy->isRoot());

auto sig = Builder.getFunction().getGenericSignature();
auto existentialTy = archetypeTy->getExistentialType()->getCanonicalType();
auto replacementTy = OpenedArchetypeType::get(
getOpASTType(existentialTy),
archetypeTy->getInterfaceType());
auto env = GenericEnvironment::forOpenedExistential(
getOpASTType(existentialTy), sig, UUID::fromTime());
auto interfaceTy = OpenedArchetypeType::getSelfInterfaceTypeFromContext(sig, existentialTy->getASTContext());
auto replacementTy =
env->mapTypeIntoContext(interfaceTy)
->template castTo<OpenedArchetypeType>();
registerOpenedExistentialRemapping(archetypeTy, replacementTy);
}

Expand Down
4 changes: 4 additions & 0 deletions include/swift/SIL/SILFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,10 @@ class SILFunction
GenericEnv = env;
}

/// Retrieve the generic signature from the generic environment of this
/// function, if any. Else returns the null \c GenericSignature.
GenericSignature getGenericSignature() const;

/// Map the given type, which is based on an interface SILFunctionType and may
/// therefore be dependent, to a type based on the context archetypes of this
/// SILFunction.
Expand Down
3 changes: 2 additions & 1 deletion include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -5585,7 +5585,8 @@ Expr *getArgumentLabelTargetExpr(Expr *fn);
/// the given type variable, type-erase occurences of that opened type
/// variable and anything that depends on it to their non-dependent bounds.
Type typeEraseOpenedExistentialReference(Type type, Type existentialBaseType,
TypeVariableType *openedTypeVar);
TypeVariableType *openedTypeVar,
const DeclContext *useDC);

/// 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