Skip to content

Commit 3715bc7

Browse files
authored
Merge pull request swiftlang#38416 from apple/revert-38384-generic-environment-cleanup
Revert "Begin untangling GenericEnvironment from GenericSignatureBuilder"
2 parents 1d84409 + d783b6a commit 3715bc7

File tree

8 files changed

+248
-171
lines changed

8 files changed

+248
-171
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,16 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
7676
/// generic signature.
7777
ArrayRef<Type> getContextTypes() const;
7878

79-
explicit GenericEnvironment(GenericSignature signature);
79+
GenericEnvironment(GenericSignature signature,
80+
GenericSignatureBuilder *builder);
8081

8182
friend ArchetypeType;
8283
friend GenericSignatureBuilder;
8384

84-
GenericSignatureBuilder *getGenericSignatureBuilder() const;
85+
GenericSignatureBuilder *getGenericSignatureBuilder() const { return Builder; }
8586

8687
friend QueryInterfaceTypeSubstitutions;
8788

88-
Type getOrCreateArchetypeFromInterfaceType(Type depType);
89-
90-
/// Retrieve the mapping for the given generic parameter, if present.
91-
///
92-
/// This is only useful when lazily populating a generic environment.
93-
Optional<Type> getMappingIfPresent(GenericParamKey key) const;
94-
9589
public:
9690
GenericSignature getGenericSignature() const {
9791
return Signature;
@@ -102,12 +96,18 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
10296
/// Create a new, "incomplete" generic environment that will be populated
10397
/// by calls to \c addMapping().
10498
static
105-
GenericEnvironment *getIncomplete(GenericSignature signature);
99+
GenericEnvironment *getIncomplete(GenericSignature signature,
100+
GenericSignatureBuilder *builder);
106101

107102
/// Add a mapping of a generic parameter to a specific type (which may be
108103
/// an archetype)
109104
void addMapping(GenericParamKey key, Type contextType);
110105

106+
/// Retrieve the mapping for the given generic parameter, if present.
107+
///
108+
/// This is only useful when lazily populating a generic environment.
109+
Optional<Type> getMappingIfPresent(GenericParamKey key) const;
110+
111111
/// Make vanilla new/delete illegal.
112112
void *operator new(size_t Bytes) = delete;
113113
void operator delete(void *Data) = delete;
@@ -151,8 +151,6 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
151151
mapConformanceRefIntoContext(Type conformingType,
152152
ProtocolConformanceRef conformance) const;
153153

154-
/// Returns a substitution map that sends every generic parameter to its
155-
/// corresponding archetype in this generic environment.
156154
SubstitutionMap getForwardingSubstitutionMap() const;
157155

158156
void dump(raw_ostream &os) const;

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,24 @@ class GenericSignatureBuilder {
228228

229229
/// Lookup a nested type with the given name within this equivalence
230230
/// class.
231+
///
232+
/// \param otherConcreteTypes If non-null, will be filled in the all of the
233+
/// concrete types we found (other than the result) with the same name.
231234
TypeDecl *lookupNestedType(
232235
GenericSignatureBuilder &builder,
233-
Identifier name);
236+
Identifier name,
237+
SmallVectorImpl<TypeDecl *> *otherConcreteTypes = nullptr);
234238

235239
/// Retrieve the "anchor" type that canonically describes this equivalence
236240
/// class, for use in the canonical type.
237241
Type getAnchor(GenericSignatureBuilder &builder,
238242
TypeArrayView<GenericTypeParamType> genericParams);
239243

244+
/// Retrieve (or build) the contextual type corresponding to
245+
/// this equivalence class within the given generic environment.
246+
Type getTypeInContext(GenericSignatureBuilder &builder,
247+
GenericEnvironment *genericEnv);
248+
240249
/// Dump a debugging representation of this equivalence class,
241250
void dump(llvm::raw_ostream &out,
242251
GenericSignatureBuilder *builder = nullptr) const;
@@ -259,7 +268,7 @@ class GenericSignatureBuilder {
259268
unsigned numConformancesPresent;
260269
CanType superclassPresent;
261270
CanType concreteTypePresent;
262-
TypeDecl *type;
271+
llvm::TinyPtrVector<TypeDecl *> types;
263272
};
264273

265274
/// Cached nested-type information, which contains the best declaration

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4165,7 +4165,8 @@ OpaqueTypeArchetypeType::get(OpaqueTypeDecl *Decl,
41654165

41664166
// Create a generic environment and bind the opaque archetype to the
41674167
// opaque interface type from the decl's signature.
4168-
auto *env = GenericEnvironment::getIncomplete(signature);
4168+
auto *builder = signature->getGenericSignatureBuilder();
4169+
auto *env = GenericEnvironment::getIncomplete(signature, builder);
41694170
env->addMapping(GenericParamKey(opaqueInterfaceTy), newOpaque);
41704171
newOpaque->Environment = env;
41714172

@@ -4242,7 +4243,8 @@ GenericEnvironment *OpenedArchetypeType::getGenericEnvironment() const {
42424243
auto &ctx = thisType->getASTContext();
42434244
// Create a generic environment to represent the opened type.
42444245
auto signature = ctx.getOpenedArchetypeSignature(Opened);
4245-
auto *env = GenericEnvironment::getIncomplete(signature);
4246+
auto *builder = signature->getGenericSignatureBuilder();
4247+
auto *env = GenericEnvironment::getIncomplete(signature, builder);
42464248
env->addMapping(signature->getGenericParams()[0], thisType);
42474249
Environment = env;
42484250

@@ -4397,14 +4399,15 @@ GenericSignature::get(TypeArrayView<GenericTypeParamType> params,
43974399
}
43984400

43994401
GenericEnvironment *GenericEnvironment::getIncomplete(
4400-
GenericSignature signature) {
4402+
GenericSignature signature,
4403+
GenericSignatureBuilder *builder) {
44014404
auto &ctx = signature->getASTContext();
44024405

44034406
// Allocate and construct the new environment.
44044407
unsigned numGenericParams = signature->getGenericParams().size();
44054408
size_t bytes = totalSizeToAlloc<Type>(numGenericParams);
44064409
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
4407-
return new (mem) GenericEnvironment(signature);
4410+
return new (mem) GenericEnvironment(signature, builder);
44084411
}
44094412

44104413
void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,

lib/AST/GenericEnvironment.cpp

Lines changed: 22 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
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"
2321

2422
using namespace swift;
2523

@@ -48,24 +46,15 @@ GenericEnvironment::getGenericParams() const {
4846
return Signature->getGenericParams();
4947
}
5048

51-
GenericEnvironment::GenericEnvironment(GenericSignature signature)
52-
: Signature(signature)
49+
GenericEnvironment::GenericEnvironment(GenericSignature signature,
50+
GenericSignatureBuilder *builder)
51+
: Signature(signature), Builder(builder)
5352
{
5453
// Clear out the memory that holds the context types.
5554
std::uninitialized_fill(getContextTypes().begin(), getContextTypes().end(),
5655
Type());
5756
}
5857

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-
6958
void GenericEnvironment::addMapping(GenericParamKey key,
7059
Type contextType) {
7160
// Find the index into the parallel arrays of generic parameters and
@@ -75,9 +64,7 @@ void GenericEnvironment::addMapping(GenericParamKey key,
7564
assert(genericParams[index] == key && "Bad generic parameter");
7665

7766
// Add the mapping from the generic parameter to the context type.
78-
assert(getContextTypes()[index].isNull() ||
79-
getContextTypes()[index]->is<ErrorType>() &&
80-
"Already recoded this mapping");
67+
assert(getContextTypes()[index].isNull() && "Already recoded this mapping");
8168
getContextTypes()[index] = contextType;
8269
}
8370

@@ -120,116 +107,6 @@ Type TypeBase::mapTypeOutOfContext() {
120107
SubstFlags::AllowLoweredTypes);
121108
}
122109

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-
233110
Type QueryInterfaceTypeSubstitutions::operator()(SubstitutableType *type) const{
234111
if (auto gp = type->getAs<GenericTypeParamType>()) {
235112
// Find the index into the parallel arrays of generic parameters and
@@ -243,18 +120,24 @@ Type QueryInterfaceTypeSubstitutions::operator()(SubstitutableType *type) const{
243120
return Type();
244121

245122
// If the context type isn't already known, lazily create it.
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;
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;
258141
}
259142

260143
return Type();

lib/AST/GenericSignature.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,9 @@ CanGenericSignature GenericSignatureImpl::getCanonicalSignature() const {
247247

248248
GenericEnvironment *GenericSignatureImpl::getGenericEnvironment() const {
249249
if (GenericEnv == nullptr) {
250+
auto *builder = getGenericSignatureBuilder();
250251
const auto impl = const_cast<GenericSignatureImpl *>(this);
251-
impl->GenericEnv = GenericEnvironment::getIncomplete(this);
252+
impl->GenericEnv = GenericEnvironment::getIncomplete(this, builder);
252253
}
253254

254255
return GenericEnv;

0 commit comments

Comments
 (0)