Skip to content

Commit 15d96ef

Browse files
authored
Merge pull request #41677 from CodaFi/substitutions-available-upon-request
Place Opened Archetypes in their Proper Generic Contexts
2 parents 0056129 + f694bf5 commit 15d96ef

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+457
-198
lines changed

include/swift/AST/ASTContext.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,8 +1298,17 @@ class ASTContext final {
12981298
CanGenericSignature getSingleGenericParameterSignature() const;
12991299

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

13041313
GenericSignature getOverrideGenericSignature(const ValueDecl *base,
13051314
const ValueDecl *derived);

include/swift/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2693,7 +2693,8 @@ class ValueDecl : public Decl {
26932693
/// property, or the uncurried result type of a method/subscript, e.g.
26942694
/// '() -> () -> Self'.
26952695
GenericParameterReferenceInfo findExistentialSelfReferences(
2696-
Type baseTy, bool treatNonResultCovariantSelfAsInvariant) const;
2696+
Type baseTy, const DeclContext *useDC,
2697+
bool treatNonResultCovariantSelfAsInvariant) const;
26972698
};
26982699

26992700
/// This is a common base class for declarations which declare a type.

include/swift/AST/GenericEnvironment.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,29 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
157157
GenericEnvironment *getIncomplete(GenericSignature signature);
158158

159159
/// Create a new generic environment for an opened existential.
160-
static GenericEnvironment *forOpenedExistential(Type existential, UUID uuid);
160+
///
161+
/// This function uses the provided parent signature to construct a new
162+
/// signature suitable for use with an opened archetype. If you have an
163+
/// existing generic signature from e.g. deserialization use
164+
/// \c GenericEnvironment::forOpenedArchetypeSignature instead.
165+
///
166+
/// \param existential The subject existential type
167+
/// \param parentSig The signature of the context where this existential type is being opened
168+
/// \param uuid The unique identifier for this opened existential
169+
static GenericEnvironment *
170+
forOpenedExistential(Type existential, GenericSignature parentSig, UUID uuid);
171+
172+
/// Create a new generic environment for an opened existential.
173+
///
174+
/// It is unlikely you want to use this function.
175+
/// Call \c GenericEnvironment::forOpenedExistential instead.
176+
///
177+
/// \param existential The subject existential type
178+
/// \param signature The signature of the opened archetype
179+
/// \param uuid The unique identifier for this opened existential
180+
static GenericEnvironment *
181+
forOpenedArchetypeSignature(Type existential,
182+
GenericSignature signature, UUID uuid);
161183

162184
/// Create a new generic environment for an opaque type with the given set of
163185
/// outer substitutions.

include/swift/AST/Types.h

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
507507
/// Canonical protocol composition types are minimized only to a certain
508508
/// degree to preserve ABI compatibility. This routine enables performing
509509
/// slower, but stricter minimization at need (e.g. redeclaration checking).
510-
CanType getMinimalCanonicalType() const;
510+
CanType getMinimalCanonicalType(const DeclContext *useDC) const;
511511

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

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

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

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

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

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

52745276
ProtocolType *Base;
5275-
Type Arg;
52765277

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

5749+
public:
5750+
/// Compute the parameter that serves as the \c Self type for an opened
5751+
/// archetype from the given outer generic signature.
5752+
///
5753+
/// This type is a generic parameter one level deeper
5754+
/// than the deepest generic context depth.
5755+
static Type getSelfInterfaceTypeFromContext(GenericSignature parentSig,
5756+
ASTContext &ctx);
5757+
57485758
public:
57495759
/// Get or create an archetype that represents the opened type
57505760
/// of an existential value.
57515761
///
57525762
/// \param existential The existential type to open.
5763+
/// \param parentSig The generic signature of the context opening
5764+
/// this existential.
57535765
///
57545766
/// \param knownID When non-empty, the known ID of the archetype. When empty,
57555767
/// a fresh archetype with a unique ID will be opened.
5756-
static CanTypeWrapper<OpenedArchetypeType> get(
5757-
CanType existential, Optional<UUID> knownID = None);
5768+
static CanTypeWrapper<OpenedArchetypeType> get(CanType existential,
5769+
GenericSignature parentSig,
5770+
Optional<UUID> knownID = None);
57585771

57595772
/// Get or create an archetype that represents the opened type
57605773
/// of an existential value.
57615774
///
57625775
/// \param existential The existential type to open.
57635776
/// \param interfaceType The interface type represented by this archetype.
5777+
/// \param parentSig The generic signature of the context opening
5778+
/// this existential.
57645779
///
57655780
/// \param knownID When non-empty, the known ID of the archetype. When empty,
57665781
/// a fresh archetype with a unique ID will be opened.
5767-
static CanTypeWrapper<OpenedArchetypeType> get(
5768-
CanType existential, Type interfaceType, Optional<UUID> knownID = None);
5782+
static CanTypeWrapper<OpenedArchetypeType> get(CanType existential,
5783+
Type interfaceType,
5784+
GenericSignature parentSig,
5785+
Optional<UUID> knownID = None);
57695786

57705787
/// Create a new archetype that represents the opened type
57715788
/// of an existential value.
57725789
///
5790+
/// Use this function when you are unsure of whether the
5791+
/// \c existential type is a metatype or an instance type. This function
5792+
/// will unwrap any existential metatype containers.
5793+
///
57735794
/// \param existential The existential type or existential metatype to open.
57745795
/// \param interfaceType The interface type represented by this archetype.
5775-
static CanType getAny(CanType existential, Type interfaceType);
5796+
/// \param parentSig The generic signature of the context opening
5797+
/// this existential.
5798+
static CanType getAny(CanType existential, Type interfaceType,
5799+
GenericSignature parentSig);
57765800

57775801
/// Create a new archetype that represents the opened type
57785802
/// of an existential value.
57795803
///
5804+
/// Use this function when you are unsure of whether the
5805+
/// \c existential type is a metatype or an instance type. This function
5806+
/// will unwrap any existential metatype containers.
5807+
///
57805808
/// \param existential The existential type or existential metatype to open.
5781-
static CanType getAny(CanType existential);
5809+
/// \param parentSig The generic signature of the context opening
5810+
/// this existential.
5811+
static CanType getAny(CanType existential, GenericSignature parentSig);
57825812

57835813
/// Retrieve the ID number of this opened existential.
57845814
UUID getOpenedExistentialID() const;

include/swift/SIL/SILCloner.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_SIL_SILCLONER_H
1818
#define SWIFT_SIL_SILCLONER_H
1919

20+
#include "swift/AST/GenericEnvironment.h"
2021
#include "swift/AST/ProtocolConformance.h"
2122
#include "swift/SIL/BasicBlockUtils.h"
2223
#include "swift/SIL/DebugUtils.h"
@@ -251,10 +252,14 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
251252
void remapRootOpenedType(CanOpenedArchetypeType archetypeTy) {
252253
assert(archetypeTy->isRoot());
253254

255+
auto sig = Builder.getFunction().getGenericSignature();
254256
auto existentialTy = archetypeTy->getExistentialType()->getCanonicalType();
255-
auto replacementTy = OpenedArchetypeType::get(
256-
getOpASTType(existentialTy),
257-
archetypeTy->getInterfaceType());
257+
auto env = GenericEnvironment::forOpenedExistential(
258+
getOpASTType(existentialTy), sig, UUID::fromTime());
259+
auto interfaceTy = OpenedArchetypeType::getSelfInterfaceTypeFromContext(sig, existentialTy->getASTContext());
260+
auto replacementTy =
261+
env->mapTypeIntoContext(interfaceTy)
262+
->template castTo<OpenedArchetypeType>();
258263
registerOpenedExistentialRemapping(archetypeTy, replacementTy);
259264
}
260265

include/swift/SIL/SILFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,10 @@ class SILFunction
10491049
GenericEnv = env;
10501050
}
10511051

1052+
/// Retrieve the generic signature from the generic environment of this
1053+
/// function, if any. Else returns the null \c GenericSignature.
1054+
GenericSignature getGenericSignature() const;
1055+
10521056
/// Map the given type, which is based on an interface SILFunctionType and may
10531057
/// therefore be dependent, to a type based on the context archetypes of this
10541058
/// SILFunction.

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5585,7 +5585,8 @@ Expr *getArgumentLabelTargetExpr(Expr *fn);
55855585
/// the given type variable, type-erase occurences of that opened type
55865586
/// variable and anything that depends on it to their non-dependent bounds.
55875587
Type typeEraseOpenedExistentialReference(Type type, Type existentialBaseType,
5588-
TypeVariableType *openedTypeVar);
5588+
TypeVariableType *openedTypeVar,
5589+
const DeclContext *useDC);
55895590

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

0 commit comments

Comments
 (0)