Skip to content

Commit 26fffae

Browse files
committed
AST: Simplify SubstitutionMap representation
There was a bunch of logic to lazily populate replacement types corresponding to reducible generic parameters. This didn't seem to have a clear purpose so let's remove it.
1 parent 977b444 commit 26fffae

File tree

8 files changed

+38
-141
lines changed

8 files changed

+38
-141
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,6 @@ class SubstitutionMap {
7373
/// signature nor any replacement types/conformances.
7474
Storage *storage = nullptr;
7575

76-
public:
77-
/// Retrieve the array of replacement types, which line up with the
78-
/// generic parameters.
79-
///
80-
/// Note that the types may be null, for cases where the generic parameter
81-
/// is concrete but hasn't been queried yet.
82-
///
83-
/// Prefer \c getReplacementTypes, this is public for printing purposes.
84-
ArrayRef<Type> getReplacementTypesBuffer() const;
85-
86-
private:
87-
MutableArrayRef<Type> getReplacementTypesBuffer();
88-
89-
/// Retrieve a mutable reference to the buffer of conformances.
90-
MutableArrayRef<ProtocolConformanceRef> getConformancesBuffer();
91-
9276
/// Form a substitution map for the given generic signature with the
9377
/// specified replacement types and conformances.
9478
SubstitutionMap(GenericSignature genericSig,

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,21 +5296,11 @@ void SubstitutionMap::Storage::Profile(
52965296
id.AddPointer(genericSig.getPointer());
52975297
if (!genericSig) return;
52985298

5299-
// Profile those replacement types that corresponding to canonical generic
5300-
// parameters within the generic signature.
5301-
id.AddInteger(replacementTypes.size());
5302-
5303-
unsigned i = 0;
5304-
genericSig->forEachParam([&](GenericTypeParamType *gp, bool canonical) {
5305-
if (canonical)
5306-
id.AddPointer(replacementTypes[i].getPointer());
5307-
else
5308-
id.AddPointer(nullptr);
5309-
++i;
5310-
});
5299+
// Replacement types.
5300+
for (auto replacementType : replacementTypes)
5301+
id.AddPointer(replacementType.getPointer());
53115302

53125303
// Conformances.
5313-
id.AddInteger(conformances.size());
53145304
for (auto conformance : conformances)
53155305
id.AddPointer(conformance.getOpaqueValue());
53165306
}

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3816,16 +3816,13 @@ class PrintConformance : public PrintBase {
38163816

38173817
auto genericParams = genericSig.getGenericParams();
38183818
auto replacementTypes =
3819-
static_cast<const SubstitutionMap &>(map).getReplacementTypesBuffer();
3819+
static_cast<const SubstitutionMap &>(map).getReplacementTypes();
38203820
for (unsigned i : indices(genericParams)) {
38213821
if (style == SubstitutionMap::DumpStyle::Minimal) {
38223822
printFieldRaw([&](raw_ostream &out) {
38233823
genericParams[i]->print(out);
38243824
out << " -> ";
3825-
if (replacementTypes[i])
3826-
out << replacementTypes[i];
3827-
else
3828-
out << "<unresolved concrete type>";
3825+
out << replacementTypes[i];
38293826
}, "");
38303827
} else {
38313828
printRecArbitrary([&](StringRef label) {
@@ -3834,8 +3831,7 @@ class PrintConformance : public PrintBase {
38343831
genericParams[i]->print(out);
38353832
out << " -> ";
38363833
}, "");
3837-
if (replacementTypes[i])
3838-
printRec(replacementTypes[i]);
3834+
printRec(replacementTypes[i]);
38393835
printFoot();
38403836
});
38413837
}

lib/AST/SubstitutionMap.cpp

Lines changed: 19 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ SubstitutionMap::Storage::Storage(
5555
getReplacementTypes().data());
5656
std::copy(conformances.begin(), conformances.end(),
5757
getConformances().data());
58-
populatedAllReplacements = false;
5958
}
6059

6160
SubstitutionMap::SubstitutionMap(
@@ -69,20 +68,6 @@ SubstitutionMap::SubstitutionMap(
6968
#endif
7069
}
7170

72-
ArrayRef<Type> SubstitutionMap::getReplacementTypesBuffer() const {
73-
return storage ? storage->getReplacementTypes() : ArrayRef<Type>();
74-
}
75-
76-
MutableArrayRef<Type> SubstitutionMap::getReplacementTypesBuffer() {
77-
return storage ? storage->getReplacementTypes() : MutableArrayRef<Type>();
78-
}
79-
80-
MutableArrayRef<ProtocolConformanceRef>
81-
SubstitutionMap::getConformancesBuffer() {
82-
return storage ? storage->getConformances()
83-
: MutableArrayRef<ProtocolConformanceRef>();
84-
}
85-
8671
ArrayRef<ProtocolConformanceRef> SubstitutionMap::getConformances() const {
8772
return storage ? storage->getConformances()
8873
: ArrayRef<ProtocolConformanceRef>();
@@ -91,16 +76,7 @@ ArrayRef<ProtocolConformanceRef> SubstitutionMap::getConformances() const {
9176
ArrayRef<Type> SubstitutionMap::getReplacementTypes() const {
9277
if (empty()) return { };
9378

94-
// Make sure we've filled in all of the replacement types.
95-
if (!storage->populatedAllReplacements) {
96-
for (auto gp : getGenericSignature().getGenericParams()) {
97-
(void)lookupSubstitution(cast<SubstitutableType>(gp->getCanonicalType()));
98-
}
99-
100-
storage->populatedAllReplacements = true;
101-
}
102-
103-
return getReplacementTypesBuffer();
79+
return storage->getReplacementTypes();
10480
}
10581

10682
ArrayRef<Type> SubstitutionMap::getInnermostReplacementTypes() const {
@@ -126,32 +102,32 @@ bool SubstitutionMap::hasAnySubstitutableParams() const {
126102
}
127103

128104
bool SubstitutionMap::hasArchetypes() const {
129-
for (Type replacementTy : getReplacementTypesBuffer()) {
130-
if (replacementTy && replacementTy->hasArchetype())
105+
for (Type replacementTy : getReplacementTypes()) {
106+
if (replacementTy->hasArchetype())
131107
return true;
132108
}
133109
return false;
134110
}
135111

136112
bool SubstitutionMap::hasLocalArchetypes() const {
137-
for (Type replacementTy : getReplacementTypesBuffer()) {
138-
if (replacementTy && replacementTy->hasLocalArchetype())
113+
for (Type replacementTy : getReplacementTypes()) {
114+
if (replacementTy->hasLocalArchetype())
139115
return true;
140116
}
141117
return false;
142118
}
143119

144120
bool SubstitutionMap::hasOpaqueArchetypes() const {
145-
for (Type replacementTy : getReplacementTypesBuffer()) {
146-
if (replacementTy && replacementTy->hasOpaqueArchetype())
121+
for (Type replacementTy : getReplacementTypes()) {
122+
if (replacementTy->hasOpaqueArchetype())
147123
return true;
148124
}
149125
return false;
150126
}
151127

152128
bool SubstitutionMap::hasDynamicSelf() const {
153-
for (Type replacementTy : getReplacementTypesBuffer()) {
154-
if (replacementTy && replacementTy->hasDynamicSelfType())
129+
for (Type replacementTy : getReplacementTypes()) {
130+
if (replacementTy->hasDynamicSelfType())
155131
return true;
156132
}
157133
return false;
@@ -162,8 +138,8 @@ bool SubstitutionMap::isCanonical() const {
162138

163139
if (!getGenericSignature()->isCanonical()) return false;
164140

165-
for (Type replacementTy : getReplacementTypesBuffer()) {
166-
if (replacementTy && !replacementTy->isCanonical())
141+
for (Type replacementTy : getReplacementTypes()) {
142+
if (!replacementTy->isCanonical())
167143
return false;
168144
}
169145

@@ -182,11 +158,8 @@ SubstitutionMap SubstitutionMap::getCanonical(bool canonicalizeSignature) const
182158
if (canonicalizeSignature) sig = sig.getCanonicalSignature();
183159

184160
SmallVector<Type, 4> replacementTypes;
185-
for (Type replacementType : getReplacementTypesBuffer()) {
186-
if (replacementType)
187-
replacementTypes.push_back(replacementType->getCanonicalType());
188-
else
189-
replacementTypes.push_back(nullptr);
161+
for (Type replacementType : getReplacementTypes()) {
162+
replacementTypes.push_back(replacementType->getCanonicalType());
190163
}
191164

192165
SmallVector<ProtocolConformanceRef, 4> conformances;
@@ -237,13 +210,7 @@ SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
237210
SmallVector<Type, 4> replacementTypes;
238211
replacementTypes.reserve(genericSig.getGenericParams().size());
239212

240-
genericSig->forEachParam([&](GenericTypeParamType *gp, bool canonical) {
241-
// Don't eagerly form replacements for non-canonical generic parameters.
242-
if (!canonical) {
243-
replacementTypes.push_back(Type());
244-
return;
245-
}
246-
213+
for (auto *gp : genericSig.getGenericParams()) {
247214
// Record the replacement.
248215
Type replacement = Type(gp).subst(IFS);
249216

@@ -252,7 +219,7 @@ SubstitutionMap SubstitutionMap::get(GenericSignature genericSig,
252219
"replacement for pack parameter must be a pack type");
253220

254221
replacementTypes.push_back(replacement);
255-
});
222+
}
256223

257224
// Form the stored conformances.
258225
SmallVector<ProtocolConformanceRef, 4> conformances;
@@ -292,11 +259,7 @@ Type SubstitutionMap::lookupSubstitution(CanSubstitutableType type) const {
292259
// Find the index of the replacement type based on the generic parameter we
293260
// have.
294261
auto genericParam = cast<GenericTypeParamType>(type);
295-
auto mutableThis = const_cast<SubstitutionMap *>(this);
296-
auto replacementTypes = mutableThis->getReplacementTypesBuffer();
297-
auto genericSig = getGenericSignature();
298-
assert(genericSig);
299-
auto genericParams = genericSig.getGenericParams();
262+
auto genericParams = getGenericSignature().getGenericParams();
300263
auto replacementIndex =
301264
GenericParamKey(genericParam).findIndexIn(genericParams);
302265

@@ -305,45 +268,7 @@ Type SubstitutionMap::lookupSubstitution(CanSubstitutableType type) const {
305268
if (replacementIndex == genericParams.size())
306269
return Type();
307270

308-
// If we already have a replacement type, return it.
309-
Type &replacementType = replacementTypes[replacementIndex];
310-
if (replacementType)
311-
return replacementType;
312-
313-
// The generic parameter may have been made concrete by the generic signature,
314-
// substitute into the concrete type.
315-
if (auto concreteType = genericSig->getConcreteType(genericParam)) {
316-
// Set the replacement type to an error, to block infinite recursion.
317-
replacementType = ErrorType::get(concreteType);
318-
319-
// Substitute into the replacement type.
320-
replacementType = concreteType.subst(*this);
321-
322-
// If the generic signature is canonical, canonicalize the replacement type.
323-
if (getGenericSignature()->isCanonical())
324-
replacementType = replacementType->getCanonicalType();
325-
326-
return replacementType;
327-
}
328-
329-
// The generic parameter may not be reduced. Retrieve the reduced
330-
// type, which will be dependent.
331-
CanType canonicalType = genericSig.getReducedType(genericParam);
332-
333-
// If nothing changed, we don't have a replacement.
334-
if (canonicalType == type) return Type();
335-
336-
// If we're left with a substitutable type, substitute into that.
337-
// First, set the replacement type to an error, to block infinite recursion.
338-
replacementType = ErrorType::get(type);
339-
340-
replacementType = lookupSubstitution(cast<SubstitutableType>(canonicalType));
341-
342-
// If the generic signature is canonical, canonicalize the replacement type.
343-
if (getGenericSignature()->isCanonical())
344-
replacementType = replacementType->getCanonicalType();
345-
346-
return replacementType;
271+
return getReplacementTypes()[replacementIndex];
347272
}
348273

349274
ProtocolConformanceRef
@@ -500,12 +425,7 @@ SubstitutionMap SubstitutionMap::subst(InFlightSubstitution &IFS) const {
500425
if (empty()) return SubstitutionMap();
501426

502427
SmallVector<Type, 4> newSubs;
503-
for (Type type : getReplacementTypesBuffer()) {
504-
if (!type) {
505-
// Non-canonical parameter.
506-
newSubs.push_back(Type());
507-
continue;
508-
}
428+
for (Type type : getReplacementTypes()) {
509429
newSubs.push_back(type.subst(IFS));
510430
assert(type->is<PackType>() == newSubs.back()->is<PackType>() &&
511431
"substitution changed the pack-ness of a replacement type");
@@ -843,7 +763,7 @@ bool SubstitutionMap::isIdentity() const {
843763

844764
GenericSignature sig = getGenericSignature();
845765
bool hasNonIdentityReplacement = false;
846-
auto replacements = getReplacementTypesBuffer();
766+
auto replacements = getReplacementTypes();
847767

848768
sig->forEachParam([&](GenericTypeParamType *paramTy, bool isCanonical) {
849769
if (isCanonical) {

lib/AST/SubstitutionMapStorage.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ class SubstitutionMap::Storage final
4040

4141
/// The number of conformance requirements, cached to avoid constantly
4242
/// recomputing it on conformance-buffer access.
43-
const unsigned numConformanceRequirements : 31;
44-
45-
/// Whether we've populated all replacement types already.
46-
unsigned populatedAllReplacements : 1;
43+
const unsigned numConformanceRequirements;
4744

4845
Storage() = delete;
4946

test/IDE/complete_rdar129024996.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ extension P where Self == B<A> {
4646
func bar() {}
4747
// COMPLETE: Begin completions, 2 items
4848
// COMPLETE-DAG: Decl[StaticMethod]/Super/TypeRelation[Convertible]: foo()[#S#]; name=foo()
49-
// COMPLETE-DAG: Decl[StaticMethod]/Super/TypeRelation[Convertible]: qux()[#B<S>#]; name=qux()
49+
// COMPLETE-DAG: Decl[StaticMethod]/Super/Flair[ExprSpecific]/TypeRelation[Convertible]: qux()[#any Q#]; name=qux()

test/IDE/complete_rdar94369218.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func test3<MyGeneric: MyProto>() {
3434
#^GENERICEXPR^#
3535
// GENERICEXPR: Decl[GenericTypeParam]/Local: MyGeneric[#MyGeneric#]; name=MyGeneric
3636
// GENERICEXPR: Decl[Constructor]/Local: MyGeneric({#value: String#})[#MyProto#]; name=MyGeneric(value:)
37-
// GENERICEXPR: Decl[Constructor]/Local: MyGeneric({#arg: String#})[#MyStruct#]; name=MyGeneric(arg:)
37+
// GENERICEXPR: Decl[Constructor]/Local: MyGeneric({#arg: String#})[#MyProto#]; name=MyGeneric(arg:)
3838
}
3939
}
4040
}

test/SourceKit/DocSupport/doc_system_module_underscored.swift.response

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,16 @@ protocol Other1 {
11451145
},
11461146
{
11471147
key.kind: source.lang.swift.decl.extension.struct,
1148+
key.generic_params: [
1149+
{
1150+
key.name: "T"
1151+
}
1152+
],
1153+
key.generic_requirements: [
1154+
{
1155+
key.description: "T == String"
1156+
}
1157+
],
11481158
key.offset: 396,
11491159
key.length: 98,
11501160
key.fully_annotated_decl: "<syntaxtype.keyword>extension</syntaxtype.keyword> <ref.struct usr=\"s:16UnderscoredProto1AV\">A</ref.struct>",

0 commit comments

Comments
 (0)