Skip to content

Commit a96682c

Browse files
committed
AST: Move EquivalenceClass::getTypeInContext() to GenericEnvironment.cpp
1 parent 9d07ff7 commit a96682c

File tree

2 files changed

+123
-121
lines changed

2 files changed

+123
-121
lines changed

lib/AST/GenericEnvironment.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/ASTContext.h"
1919
#include "swift/AST/GenericSignatureBuilder.h"
2020
#include "swift/AST/ProtocolConformance.h"
21+
#include "swift/Basic/Defer.h"
2122
#include "GenericSignatureBuilderImpl.h"
2223

2324
using namespace swift;
@@ -117,6 +118,128 @@ Type TypeBase::mapTypeOutOfContext() {
117118
SubstFlags::AllowLoweredTypes);
118119
}
119120

121+
Type
122+
GenericSignatureBuilder::EquivalenceClass::getTypeInContext(
123+
GenericSignatureBuilder &builder, GenericEnvironment *genericEnv) {
124+
auto genericParams = genericEnv->getGenericParams();
125+
126+
// The anchor descr
127+
Type anchor = getAnchor(builder, genericParams);
128+
129+
// If this equivalence class is mapped to a concrete type, produce that
130+
// type.
131+
if (concreteType) {
132+
if (recursiveConcreteType)
133+
return ErrorType::get(anchor);
134+
135+
// Prevent recursive substitution.
136+
this->recursiveConcreteType = true;
137+
SWIFT_DEFER {
138+
this->recursiveConcreteType = false;
139+
};
140+
141+
return genericEnv->mapTypeIntoContext(concreteType,
142+
builder.getLookupConformanceFn());
143+
}
144+
145+
// Local function to check whether we have a generic parameter that has
146+
// already been recorded
147+
auto getAlreadyRecoveredGenericParam = [&]() -> Type {
148+
auto genericParam = anchor->getAs<GenericTypeParamType>();
149+
if (!genericParam) return Type();
150+
151+
auto type = genericEnv->getMappingIfPresent(genericParam);
152+
if (!type) return Type();
153+
154+
// We already have a mapping for this generic parameter in the generic
155+
// environment. Return it.
156+
return *type;
157+
};
158+
159+
AssociatedTypeDecl *assocType = nullptr;
160+
ArchetypeType *parentArchetype = nullptr;
161+
if (auto depMemTy = anchor->getAs<DependentMemberType>()) {
162+
// Resolve the equivalence class of the parent.
163+
auto parentEquivClass =
164+
builder.resolveEquivalenceClass(
165+
depMemTy->getBase(),
166+
ArchetypeResolutionKind::CompleteWellFormed);
167+
if (!parentEquivClass)
168+
return ErrorType::get(anchor);
169+
170+
// Map the parent type into this context.
171+
parentArchetype =
172+
parentEquivClass->getTypeInContext(builder, genericEnv)
173+
->castTo<ArchetypeType>();
174+
175+
// If we already have a nested type with this name, return it.
176+
assocType = depMemTy->getAssocType();
177+
if (auto nested =
178+
parentArchetype->getNestedTypeIfKnown(assocType->getName())) {
179+
return *nested;
180+
}
181+
182+
// We will build the archetype below.
183+
} else if (auto result = getAlreadyRecoveredGenericParam()) {
184+
// Return already-contextualized generic type parameter.
185+
return result;
186+
}
187+
188+
// Substitute into the superclass.
189+
Type superclass = this->recursiveSuperclassType ? Type() : this->superclass;
190+
if (superclass && superclass->hasTypeParameter()) {
191+
// Prevent recursive substitution.
192+
this->recursiveSuperclassType = true;
193+
SWIFT_DEFER {
194+
this->recursiveSuperclassType = false;
195+
};
196+
197+
superclass = genericEnv->mapTypeIntoContext(
198+
superclass,
199+
builder.getLookupConformanceFn());
200+
if (superclass->is<ErrorType>())
201+
superclass = Type();
202+
203+
// We might have recursively recorded the archetype; if so, return early.
204+
// FIXME: This should be detectable before we end up building archetypes.
205+
if (auto result = getAlreadyRecoveredGenericParam())
206+
return result;
207+
}
208+
209+
// Build a new archetype.
210+
211+
// Collect the protocol conformances for the archetype.
212+
SmallVector<ProtocolDecl *, 4> protos;
213+
for (const auto &conforms : conformsTo) {
214+
auto proto = conforms.first;
215+
216+
if (!isConformanceSatisfiedBySuperclass(proto))
217+
protos.push_back(proto);
218+
}
219+
220+
ArchetypeType *archetype;
221+
ASTContext &ctx = builder.getASTContext();
222+
if (parentArchetype) {
223+
// Create a nested archetype.
224+
auto *depMemTy = anchor->castTo<DependentMemberType>();
225+
archetype = NestedArchetypeType::getNew(ctx, parentArchetype, depMemTy,
226+
protos, superclass, layout);
227+
228+
// Register this archetype with its parent.
229+
parentArchetype->registerNestedType(assocType->getName(), archetype);
230+
} else {
231+
// Create a top-level archetype.
232+
auto genericParam = anchor->castTo<GenericTypeParamType>();
233+
archetype = PrimaryArchetypeType::getNew(ctx, genericEnv, genericParam,
234+
protos, superclass, layout);
235+
236+
// Register the archetype with the generic environment.
237+
genericEnv->addMapping(genericParam, archetype);
238+
}
239+
240+
return archetype;
241+
}
242+
120243
void ArchetypeType::resolveNestedType(
121244
std::pair<Identifier, Type> &nested) const {
122245
auto genericEnv = getGenericEnvironment();

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 0 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,127 +2169,6 @@ Type EquivalenceClass::getAnchor(
21692169
return substAnchor();
21702170
}
21712171

2172-
Type EquivalenceClass::getTypeInContext(GenericSignatureBuilder &builder,
2173-
GenericEnvironment *genericEnv) {
2174-
auto genericParams = genericEnv->getGenericParams();
2175-
2176-
// The anchor descr
2177-
Type anchor = getAnchor(builder, genericParams);
2178-
2179-
// If this equivalence class is mapped to a concrete type, produce that
2180-
// type.
2181-
if (concreteType) {
2182-
if (recursiveConcreteType)
2183-
return ErrorType::get(anchor);
2184-
2185-
// Prevent recursive substitution.
2186-
this->recursiveConcreteType = true;
2187-
SWIFT_DEFER {
2188-
this->recursiveConcreteType = false;
2189-
};
2190-
2191-
return genericEnv->mapTypeIntoContext(concreteType,
2192-
builder.getLookupConformanceFn());
2193-
}
2194-
2195-
// Local function to check whether we have a generic parameter that has
2196-
// already been recorded
2197-
auto getAlreadyRecoveredGenericParam = [&]() -> Type {
2198-
auto genericParam = anchor->getAs<GenericTypeParamType>();
2199-
if (!genericParam) return Type();
2200-
2201-
auto type = genericEnv->getMappingIfPresent(genericParam);
2202-
if (!type) return Type();
2203-
2204-
// We already have a mapping for this generic parameter in the generic
2205-
// environment. Return it.
2206-
return *type;
2207-
};
2208-
2209-
AssociatedTypeDecl *assocType = nullptr;
2210-
ArchetypeType *parentArchetype = nullptr;
2211-
if (auto depMemTy = anchor->getAs<DependentMemberType>()) {
2212-
// Resolve the equivalence class of the parent.
2213-
auto parentEquivClass =
2214-
builder.resolveEquivalenceClass(
2215-
depMemTy->getBase(),
2216-
ArchetypeResolutionKind::CompleteWellFormed);
2217-
if (!parentEquivClass)
2218-
return ErrorType::get(anchor);
2219-
2220-
// Map the parent type into this context.
2221-
parentArchetype =
2222-
parentEquivClass->getTypeInContext(builder, genericEnv)
2223-
->castTo<ArchetypeType>();
2224-
2225-
// If we already have a nested type with this name, return it.
2226-
assocType = depMemTy->getAssocType();
2227-
if (auto nested =
2228-
parentArchetype->getNestedTypeIfKnown(assocType->getName())) {
2229-
return *nested;
2230-
}
2231-
2232-
// We will build the archetype below.
2233-
} else if (auto result = getAlreadyRecoveredGenericParam()) {
2234-
// Return already-contextualized generic type parameter.
2235-
return result;
2236-
}
2237-
2238-
// Substitute into the superclass.
2239-
Type superclass = this->recursiveSuperclassType ? Type() : this->superclass;
2240-
if (superclass && superclass->hasTypeParameter()) {
2241-
// Prevent recursive substitution.
2242-
this->recursiveSuperclassType = true;
2243-
SWIFT_DEFER {
2244-
this->recursiveSuperclassType = false;
2245-
};
2246-
2247-
superclass = genericEnv->mapTypeIntoContext(
2248-
superclass,
2249-
builder.getLookupConformanceFn());
2250-
if (superclass->is<ErrorType>())
2251-
superclass = Type();
2252-
2253-
// We might have recursively recorded the archetype; if so, return early.
2254-
// FIXME: This should be detectable before we end up building archetypes.
2255-
if (auto result = getAlreadyRecoveredGenericParam())
2256-
return result;
2257-
}
2258-
2259-
// Build a new archetype.
2260-
2261-
// Collect the protocol conformances for the archetype.
2262-
SmallVector<ProtocolDecl *, 4> protos;
2263-
for (const auto &conforms : conformsTo) {
2264-
auto proto = conforms.first;
2265-
2266-
if (!isConformanceSatisfiedBySuperclass(proto))
2267-
protos.push_back(proto);
2268-
}
2269-
2270-
ArchetypeType *archetype;
2271-
ASTContext &ctx = builder.getASTContext();
2272-
if (parentArchetype) {
2273-
// Create a nested archetype.
2274-
auto *depMemTy = anchor->castTo<DependentMemberType>();
2275-
archetype = NestedArchetypeType::getNew(ctx, parentArchetype, depMemTy,
2276-
protos, superclass, layout);
2277-
2278-
// Register this archetype with its parent.
2279-
parentArchetype->registerNestedType(assocType->getName(), archetype);
2280-
} else {
2281-
// Create a top-level archetype.
2282-
auto genericParam = anchor->castTo<GenericTypeParamType>();
2283-
archetype = PrimaryArchetypeType::getNew(ctx, genericEnv, genericParam,
2284-
protos, superclass, layout);
2285-
2286-
// Register the archetype with the generic environment.
2287-
genericEnv->addMapping(genericParam, archetype);
2288-
}
2289-
2290-
return archetype;
2291-
}
2292-
22932172
void EquivalenceClass::dump(llvm::raw_ostream &out,
22942173
GenericSignatureBuilder *builder) const {
22952174
auto dumpSource = [&](const RequirementSource *source) {

0 commit comments

Comments
 (0)