Skip to content

Commit 99a9e95

Browse files
authored
Merge pull request #40747 from DougGregor/opaque-type-archetype-environment
2 parents 9f7d3fc + 9dcb5a5 commit 99a9e95

File tree

10 files changed

+450
-249
lines changed

10 files changed

+450
-249
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ namespace swift {
3333
class ArchetypeType;
3434
class ASTContext;
3535
class GenericTypeParamType;
36+
class OpaqueTypeDecl;
37+
class OpenedArchetypeType;
3638
class SILModule;
3739
class SILType;
3840

@@ -57,11 +59,28 @@ class QueryInterfaceTypeSubstitutions {
5759
/// TypeBase::mapTypeOutOfContext().
5860
///
5961
class alignas(1 << DeclAlignInBits) GenericEnvironment final
60-
: private llvm::TrailingObjects<GenericEnvironment, Type> {
61-
GenericSignature Signature = GenericSignature();
62+
: private llvm::TrailingObjects<
63+
GenericEnvironment, OpaqueTypeDecl *, SubstitutionMap, Type> {
64+
public:
65+
enum class Kind {
66+
/// A normal generic environment, determined only by its generic
67+
/// signature.
68+
Normal,
69+
/// A generic environment describing an opened existential archetype.
70+
OpenedExistential,
71+
/// A generic environment describing an opaque type archetype.
72+
Opaque,
73+
};
74+
75+
private:
76+
mutable llvm::PointerIntPair<GenericSignature, 2, Kind> SignatureAndKind{
77+
GenericSignature(), Kind::Normal};
6278

6379
friend TrailingObjects;
80+
friend OpaqueTypeArchetypeType;
6481

82+
size_t numTrailingObjects(OverloadToken<OpaqueTypeDecl *>) const;
83+
size_t numTrailingObjects(OverloadToken<SubstitutionMap>) const;
6584
size_t numTrailingObjects(OverloadToken<Type>) const;
6685

6786
/// Retrieve the array containing the context types associated with the
@@ -74,7 +93,9 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
7493
/// generic signature.
7594
ArrayRef<Type> getContextTypes() const;
7695

77-
explicit GenericEnvironment(GenericSignature signature);
96+
explicit GenericEnvironment(GenericSignature signature, Kind kind);
97+
explicit GenericEnvironment(
98+
GenericSignature signature, OpaqueTypeDecl *opaque, SubstitutionMap subs);
7899

79100
friend ArchetypeType;
80101
friend QueryInterfaceTypeSubstitutions;
@@ -86,18 +107,39 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
86107
/// This is only useful when lazily populating a generic environment.
87108
Optional<Type> getMappingIfPresent(GenericParamKey key) const;
88109

110+
/// Get the "raw" generic signature, without substituting into opaque
111+
/// type's signature.
112+
GenericSignature getRawGenericSignature() const;
113+
89114
public:
90-
GenericSignature getGenericSignature() const {
91-
return Signature;
92-
}
115+
GenericSignature getGenericSignature() const;
116+
117+
Kind getKind() const { return SignatureAndKind.getInt(); }
93118

94119
TypeArrayView<GenericTypeParamType> getGenericParams() const;
95120

121+
/// Retrieve the opaque type declaration for a generic environment describing
122+
/// opaque types.
123+
OpaqueTypeDecl *getOpaqueTypeDecl() const;
124+
125+
/// Retrieve the substitutions applied to an opaque type declaration to
126+
/// create a generic environment.
127+
SubstitutionMap getOpaqueSubstitutions() const;
128+
96129
/// Create a new, "incomplete" generic environment that will be populated
97130
/// by calls to \c addMapping().
98131
static
99132
GenericEnvironment *getIncomplete(GenericSignature signature);
100133

134+
/// Create a new generic environment for an opened existential.
135+
static GenericEnvironment *forOpenedExistential(
136+
GenericSignature signature, const OpenedArchetypeType *type);
137+
138+
/// Create a new generic environment for an opaque type with the given set of
139+
/// outer substitutions.
140+
static GenericEnvironment *forOpaqueType(
141+
OpaqueTypeDecl *opaque, SubstitutionMap subs, AllocationArena arena);
142+
101143
/// Add a mapping of a generic parameter to a specific type (which may be
102144
/// an archetype)
103145
void addMapping(GenericParamKey key, Type contextType);
@@ -112,6 +154,12 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
112154
return Mem;
113155
}
114156

157+
/// For an opaque archetype environment, apply the substitutions.
158+
Type maybeApplyOpaqueTypeSubstitutions(Type type) const;
159+
160+
/// Compute the canonical interface type within this environment.
161+
Type getCanonicalInterfaceType(Type interfaceType);
162+
115163
/// Map an interface type to a contextual type.
116164
static Type mapTypeIntoContext(GenericEnvironment *genericEnv,
117165
Type type);

include/swift/AST/Types.h

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5548,48 +5548,49 @@ END_CAN_TYPE_WRAPPER(PrimaryArchetypeType, ArchetypeType)
55485548

55495549
/// An archetype that represents an opaque type.
55505550
class OpaqueTypeArchetypeType final : public ArchetypeType,
5551-
public llvm::FoldingSetNode,
55525551
private ArchetypeTrailingObjects<OpaqueTypeArchetypeType>
55535552
{
55545553
friend TrailingObjects;
55555554
friend ArchetypeType;
55565555
friend GenericSignatureBuilder;
55575556

5558-
/// The declaration that defines the opaque type.
5559-
OpaqueTypeDecl *OpaqueDecl;
5560-
/// The substitutions into the interface signature of the opaque type.
5561-
SubstitutionMap Substitutions;
5562-
55635557
/// A GenericEnvironment with this opaque archetype bound to the interface
55645558
/// type of the output type from the OpaqueDecl.
5565-
GenericEnvironment *Environment;
5566-
5559+
GenericEnvironment *Environment = nullptr;
5560+
5561+
friend class GenericEnvironment;
5562+
5563+
static OpaqueTypeArchetypeType *getNew(
5564+
GenericEnvironment *environment, Type interfaceType,
5565+
ArrayRef<ProtocolDecl*> conformsTo, Type superclass,
5566+
LayoutConstraint layout);
5567+
55675568
public:
55685569
/// Get an opaque archetype representing the underlying type of the given
55695570
/// opaque type decl's opaque param with ordinal `ordinal`. For example, in
55705571
/// `(some P, some Q)`, `some P`'s type param would have ordinal 0 and `some
55715572
/// Q`'s type param would have ordinal 1.
5572-
static OpaqueTypeArchetypeType *get(OpaqueTypeDecl *Decl, unsigned ordinal,
5573-
SubstitutionMap Substitutions);
5573+
static Type get(OpaqueTypeDecl *decl, unsigned ordinal, SubstitutionMap subs);
5574+
5575+
/// Retrieve the opaque type declaration.
5576+
OpaqueTypeDecl *getDecl() const;
5577+
5578+
/// Retrieve the set of substitutions applied to the opaque type.
5579+
SubstitutionMap getSubstitutions() const;
55745580

5575-
OpaqueTypeDecl *getDecl() const {
5576-
return OpaqueDecl;
5577-
}
5578-
SubstitutionMap getSubstitutions() const {
5579-
return Substitutions;
5580-
}
5581-
55825581
/// Get the generic signature used to build out this archetype. This is
55835582
/// equivalent to the OpaqueTypeDecl's interface generic signature, with
55845583
/// all of the generic parameters aside from the opaque type's interface
55855584
/// type same-type-constrained to their substitutions for this type.
55865585
GenericSignature getBoundSignature() const;
55875586

55885587
/// Get a generic environment that has this opaque archetype bound within it.
5589-
GenericEnvironment *getGenericEnvironment() const {
5590-
return Environment;
5591-
}
5592-
5588+
GenericEnvironment *getGenericEnvironment() const;
5589+
5590+
/// Compute the canonical interface type within the environment of this
5591+
/// opaque type archetype.
5592+
CanType getCanonicalInterfaceType(Type interfaceType);
5593+
55935594
static bool classof(const TypeBase *T) {
55945595
return T->getKind() == TypeKind::OpaqueTypeArchetype;
55955596
}
@@ -5603,22 +5604,12 @@ class OpaqueTypeArchetypeType final : public ArchetypeType,
56035604
/// then the underlying type of `some P` would be ordinal 0, and `some Q` would be ordinal 1.
56045605
unsigned getOrdinal() const;
56055606

5606-
static void Profile(llvm::FoldingSetNodeID &ID,
5607-
OpaqueTypeDecl *OpaqueDecl,
5608-
unsigned ordinal,
5609-
SubstitutionMap Substitutions);
5610-
5611-
void Profile(llvm::FoldingSetNodeID &ID) {
5612-
Profile(ID, getDecl(), getOrdinal(), getSubstitutions());
5613-
};
5614-
56155607
private:
5616-
OpaqueTypeArchetypeType(OpaqueTypeDecl *OpaqueDecl,
5617-
SubstitutionMap Substitutions,
5618-
RecursiveTypeProperties Props,
5619-
Type InterfaceType,
5620-
ArrayRef<ProtocolDecl*> ConformsTo,
5621-
Type Superclass, LayoutConstraint Layout);
5608+
OpaqueTypeArchetypeType(GenericEnvironment *environment,
5609+
RecursiveTypeProperties properties,
5610+
Type interfaceType,
5611+
ArrayRef<ProtocolDecl*> conformsTo,
5612+
Type superclass, LayoutConstraint layout);
56225613
};
56235614
BEGIN_CAN_TYPE_WRAPPER(OpaqueTypeArchetypeType, ArchetypeType)
56245615
END_CAN_TYPE_WRAPPER(OpaqueTypeArchetypeType, ArchetypeType)

0 commit comments

Comments
 (0)