1818#include " swift/AST/ASTContext.h"
1919#include " swift/AST/GenericSignatureBuilder.h"
2020#include " swift/AST/ProtocolConformance.h"
21+ #include " swift/Basic/Defer.h"
22+ #include " GenericSignatureBuilderImpl.h"
2123
2224using namespace swift ;
2325
@@ -46,15 +48,24 @@ GenericEnvironment::getGenericParams() const {
4648 return Signature->getGenericParams ();
4749}
4850
49- GenericEnvironment::GenericEnvironment (GenericSignature signature,
50- GenericSignatureBuilder *builder)
51- : Signature(signature), Builder(builder)
51+ GenericEnvironment::GenericEnvironment (GenericSignature signature)
52+ : Signature(signature)
5253{
5354 // Clear out the memory that holds the context types.
5455 std::uninitialized_fill (getContextTypes ().begin (), getContextTypes ().end (),
5556 Type ());
5657}
5758
59+ GenericSignatureBuilder *GenericEnvironment::getGenericSignatureBuilder () const {
60+ if (Builder)
61+ return Builder;
62+
63+ const_cast <GenericEnvironment *>(this )->Builder
64+ = Signature->getGenericSignatureBuilder ();
65+
66+ return Builder;
67+ }
68+
5869void GenericEnvironment::addMapping (GenericParamKey key,
5970 Type contextType) {
6071 // Find the index into the parallel arrays of generic parameters and
@@ -64,7 +75,9 @@ void GenericEnvironment::addMapping(GenericParamKey key,
6475 assert (genericParams[index] == key && " Bad generic parameter" );
6576
6677 // Add the mapping from the generic parameter to the context type.
67- assert (getContextTypes ()[index].isNull () && " Already recoded this mapping" );
78+ assert (getContextTypes ()[index].isNull () ||
79+ getContextTypes ()[index]->is <ErrorType>() &&
80+ " Already recoded this mapping" );
6881 getContextTypes ()[index] = contextType;
6982}
7083
@@ -107,6 +120,116 @@ Type TypeBase::mapTypeOutOfContext() {
107120 SubstFlags::AllowLoweredTypes);
108121}
109122
123+ Type
124+ GenericEnvironment::getOrCreateArchetypeFromInterfaceType (Type depType) {
125+ auto &builder = *getGenericSignatureBuilder ();
126+ auto &ctx = builder.getASTContext ();
127+
128+ auto resolved =
129+ builder.maybeResolveEquivalenceClass (
130+ depType,
131+ ArchetypeResolutionKind::CompleteWellFormed,
132+ /* wantExactPotentialArchetype=*/ false );
133+ if (!resolved)
134+ return ErrorType::get (depType);
135+
136+ if (auto concrete = resolved.getAsConcreteType ()) {
137+ return mapTypeIntoContext (concrete,
138+ builder.getLookupConformanceFn ());
139+ }
140+
141+ auto *equivClass = resolved.getEquivalenceClass (builder);
142+
143+ auto genericParams = getGenericParams ();
144+ Type anchor = equivClass->getAnchor (builder, genericParams);
145+
146+ // First, write an ErrorType to the location where this type is cached,
147+ // to catch re-entrant lookups that might arise from an invalid generic
148+ // signature (eg, <X where X == Array<X>>).
149+ ArchetypeType *parentArchetype = nullptr ;
150+ GenericTypeParamType *genericParam = nullptr ;
151+ if (auto depMemTy = anchor->getAs <DependentMemberType>()) {
152+ parentArchetype =
153+ getOrCreateArchetypeFromInterfaceType (depMemTy->getBase ())
154+ ->getAs <ArchetypeType>();
155+ if (!parentArchetype)
156+ return ErrorType::get (depMemTy);
157+
158+ auto name = depMemTy->getName ();
159+ if (auto type = parentArchetype->getNestedTypeIfKnown (name))
160+ return *type;
161+
162+ parentArchetype->registerNestedType (name, ErrorType::get (ctx));
163+ } else {
164+ genericParam = anchor->castTo <GenericTypeParamType>();
165+ if (auto type = getMappingIfPresent (genericParam))
166+ return *type;
167+ addMapping (genericParam, ErrorType::get (ctx));
168+ }
169+
170+ Type result;
171+
172+ // If this equivalence class is mapped to a concrete type, produce that
173+ // type.
174+ if (equivClass->concreteType ) {
175+ result = mapTypeIntoContext (equivClass->concreteType ,
176+ builder.getLookupConformanceFn ());
177+ } else {
178+ // Substitute into the superclass.
179+ Type superclass = equivClass->superclass ;
180+ if (superclass && superclass->hasTypeParameter ()) {
181+ superclass = mapTypeIntoContext (superclass,
182+ builder.getLookupConformanceFn ());
183+ if (superclass->is <ErrorType>())
184+ superclass = Type ();
185+ }
186+
187+ // Collect the protocol conformances for the archetype.
188+ SmallVector<ProtocolDecl *, 4 > protos;
189+ for (const auto &conforms : equivClass->conformsTo ) {
190+ auto proto = conforms.first ;
191+
192+ if (!equivClass->isConformanceSatisfiedBySuperclass (proto))
193+ protos.push_back (proto);
194+ }
195+
196+ if (parentArchetype) {
197+ auto *depMemTy = anchor->castTo <DependentMemberType>();
198+ result = NestedArchetypeType::getNew (ctx, parentArchetype, depMemTy,
199+ protos, superclass,
200+ equivClass->layout );
201+ } else {
202+ result = PrimaryArchetypeType::getNew (ctx, this , genericParam,
203+ protos, superclass,
204+ equivClass->layout );
205+ }
206+ }
207+
208+ // Cache the new archetype for future lookups.
209+ if (auto depMemTy = anchor->getAs <DependentMemberType>()) {
210+ parentArchetype->registerNestedType (depMemTy->getName (), result);
211+ } else {
212+ addMapping (genericParam, result);
213+ }
214+
215+ return result;
216+ }
217+
218+ void ArchetypeType::resolveNestedType (
219+ std::pair<Identifier, Type> &nested) const {
220+ Type interfaceType = getInterfaceType ();
221+ Type memberInterfaceType =
222+ DependentMemberType::get (interfaceType, nested.first );
223+
224+ Type result = getGenericEnvironment ()->getOrCreateArchetypeFromInterfaceType (
225+ memberInterfaceType);
226+
227+ assert (!nested.second ||
228+ nested.second ->isEqual (result) ||
229+ nested.second ->is <ErrorType>());
230+ nested.second = result;
231+ }
232+
110233Type QueryInterfaceTypeSubstitutions::operator ()(SubstitutableType *type) const {
111234 if (auto gp = type->getAs <GenericTypeParamType>()) {
112235 // Find the index into the parallel arrays of generic parameters and
@@ -120,24 +243,18 @@ Type QueryInterfaceTypeSubstitutions::operator()(SubstitutableType *type) const{
120243 return Type ();
121244
122245 // If the context type isn't already known, lazily create it.
123- Type contextType = self->getContextTypes ()[index];
124- if (!contextType) {
125- assert (self->Builder &&" Missing generic signature builder for lazy query" );
126- auto equivClass =
127- self->Builder ->resolveEquivalenceClass (
128- type,
129- ArchetypeResolutionKind::CompleteWellFormed);
130-
131- auto mutableSelf = const_cast <GenericEnvironment *>(self);
132- contextType = equivClass->getTypeInContext (*mutableSelf->Builder ,
133- mutableSelf);
134-
135- // FIXME: Redundant mapping from key -> index.
136- if (self->getContextTypes ()[index].isNull ())
137- mutableSelf->addMapping (key, contextType);
138- }
139-
140- return contextType;
246+ auto mutableSelf = const_cast <GenericEnvironment *>(self);
247+ Type &contextType = mutableSelf->getContextTypes ()[index];
248+ if (contextType)
249+ return contextType;
250+
251+ auto result = mutableSelf->getOrCreateArchetypeFromInterfaceType (type);
252+
253+ assert (!contextType ||
254+ contextType->isEqual (result) ||
255+ contextType->is <ErrorType>());
256+ contextType = result;
257+ return result;
141258 }
142259
143260 return Type ();
0 commit comments