Skip to content

Commit 801ef51

Browse files
committed
[GSB] Resolve type into an equivalence class without building a new PA.
Teach GenericSignatureBuilder::resolveEquivalenceClass() to perform resolution of a type into a dependent type and its equivalence class without realizing that potential archetype. Improves type-checking time for the standard library by ~6%.
1 parent 9a563ce commit 801ef51

File tree

2 files changed

+83
-17
lines changed

2 files changed

+83
-17
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,13 @@ class GenericSignatureBuilder {
758758
resolvePotentialArchetype(Type type,
759759
ArchetypeResolutionKind resolutionKind);
760760

761+
private:
762+
/// \brief Try to resolvew the equivalence class of the given type.
763+
ResolveResult maybeResolveEquivalenceClass(
764+
Type type,
765+
ArchetypeResolutionKind resolutionKind);
766+
767+
public:
761768
/// \brief Resolve the equivalence class for the given type parameter,
762769
/// which provides information about that type.
763770
///

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,6 +2209,11 @@ class GenericSignatureBuilder::ResolveResult {
22092209
llvm::PointerUnion<Type, PotentialArchetype *> type;
22102210
EquivalenceClass *equivClass;
22112211

2212+
/// For a type that could not be resolved further unless the given
2213+
/// equivalence class changes.
2214+
ResolveResult(EquivalenceClass *equivClass)
2215+
: type(), equivClass(equivClass) { }
2216+
22122217
public:
22132218
/// A specific resolved potential archetype.
22142219
ResolveResult(PotentialArchetype *pa)
@@ -2221,17 +2226,26 @@ class GenericSignatureBuilder::ResolveResult {
22212226
"type parameters must have equivalence classes");
22222227
}
22232228

2224-
/// For a type that could not be resolved further unless the given
2225-
/// equivalence class changes.
2226-
ResolveResult(EquivalenceClass *equivClass)
2227-
: type(), equivClass(equivClass) { }
2229+
/// Return an unresolved result, which could be resolved when we
2230+
/// learn more information about the given equivalence class.
2231+
static ResolveResult forUnresolved(EquivalenceClass *equivClass){
2232+
return ResolveResult(equivClass);
2233+
}
22282234

22292235
/// Determine whether this result was resolved.
22302236
explicit operator bool() const { return !type.isNull(); }
22312237

22322238
/// Retrieve the resolved type.
22332239
ResolvedType getResolvedType(GenericSignatureBuilder &builder) const;
22342240

2241+
/// Retrieve the dependent type.
2242+
Type getDependentType() const;
2243+
2244+
/// Retrieve the potential archetype, if already known.
2245+
PotentialArchetype *getAsPotentialArchetype() const {
2246+
return type.dyn_cast<PotentialArchetype *>();
2247+
}
2248+
22352249
/// Retrieve the equivalence class into which a resolved type refers.
22362250
EquivalenceClass *getEquivalenceClass() const {
22372251
assert(*this && "Only for resolved types");
@@ -2271,6 +2285,14 @@ ResolvedType ResolveResult::getResolvedType(
22712285
return ResolvedType::forPotentialArchetype(pa);
22722286
}
22732287

2288+
Type ResolveResult::getDependentType() const {
2289+
// Already-resolved potential archetype.
2290+
if (auto pa = type.dyn_cast<PotentialArchetype *>())
2291+
return pa->getDependentType({ });
2292+
2293+
return type.get<Type>();
2294+
}
2295+
22742296
/// If there is a same-type requirement to be added for the given nested type
22752297
/// due to a superclass constraint on the parent type, add it now.
22762298
static void maybeAddSameTypeRequirementForNestedType(
@@ -3038,48 +3060,83 @@ auto GenericSignatureBuilder::resolvePotentialArchetype(
30383060
return (EquivalenceClass *)nullptr;
30393061
}
30403062

3041-
EquivalenceClass *GenericSignatureBuilder::resolveEquivalenceClass(
3063+
ResolveResult GenericSignatureBuilder::maybeResolveEquivalenceClass(
30423064
Type type,
30433065
ArchetypeResolutionKind resolutionKind) {
30443066
// The equivalence class of a generic type is known directly.
30453067
if (auto genericParam = type->getAs<GenericTypeParamType>()) {
30463068
unsigned index = GenericParamKey(genericParam).findIndexIn(
30473069
Impl->GenericParams);
3048-
if (index < Impl->GenericParams.size())
3049-
return Impl->PotentialArchetypes[index]->getOrCreateEquivalenceClass();
3070+
if (index < Impl->GenericParams.size()) {
3071+
auto pa = Impl->PotentialArchetypes[index];
3072+
return ResolveResult(type, pa->getOrCreateEquivalenceClass());
3073+
}
30503074

3051-
return nullptr;
3075+
return ResolveResult::forUnresolved(nullptr);
30523076
}
30533077

30543078
// The equivalence class of a dependent member type is determined by its
30553079
// base equivalence class.
30563080
if (auto depMemTy = type->getAs<DependentMemberType>()) {
30573081
// Find the equivalence class of the base.
3058-
auto baseEquivClass = resolveEquivalenceClass(depMemTy->getBase(),
3059-
resolutionKind);
3060-
if (!baseEquivClass) return nullptr;
3082+
auto resolvedBase = maybeResolveEquivalenceClass(depMemTy->getBase(),
3083+
resolutionKind);
3084+
if (!resolvedBase) return resolvedBase;
30613085

30623086
// Find the nested type declaration for this.
3087+
auto baseEquivClass = resolvedBase.getEquivalenceClass();
30633088
TypeDecl *nestedTypeDecl;
30643089
if (auto assocType = depMemTy->getAssocType()) {
30653090
nestedTypeDecl = assocType;
30663091
} else {
30673092
nestedTypeDecl = baseEquivClass->lookupNestedType(depMemTy->getName());
3068-
if (!nestedTypeDecl) return nullptr;
3093+
if (!nestedTypeDecl) {
3094+
return ResolveResult::forUnresolved(baseEquivClass);
3095+
}
30693096
}
30703097

3071-
// Retrieve the anchor of the base equivalence class.
3098+
// Retrieve the anchor of the base equivalence class, and use that to
3099+
// find the nested potential archetype corresponding to this dependent
3100+
// type.
30723101
auto baseAnchorPA =
30733102
baseEquivClass->members.front()->getArchetypeAnchor(*this);
30743103
auto nestedPA =
30753104
baseAnchorPA->updateNestedTypeForConformance(nestedTypeDecl,
30763105
resolutionKind);
30773106
if (!nestedPA)
3078-
return nullptr;
3107+
return ResolveResult::forUnresolved(baseEquivClass);
3108+
3109+
// If base resolved to the anchor, then the nested potential archetype
3110+
// we found is the resolved potential archetype. Return it directly,
3111+
// so it doesn't need to be resolved again.
3112+
if (baseAnchorPA == resolvedBase.getAsPotentialArchetype())
3113+
return ResolveResult(nestedPA);
3114+
3115+
// Compute the resolved dependent type to return.
3116+
Type resolvedBaseType = resolvedBase.getDependentType();
3117+
Type resolvedMemberType;
3118+
if (auto assocType = dyn_cast<AssociatedTypeDecl>(nestedTypeDecl)) {
3119+
resolvedMemberType =
3120+
DependentMemberType::get(resolvedBaseType, assocType);
3121+
} else {
3122+
// Note: strange case that might not even really be dependent.
3123+
resolvedMemberType =
3124+
DependentMemberType::get(resolvedBaseType, depMemTy->getName());
3125+
}
30793126

3080-
return nestedPA->getOrCreateEquivalenceClass();
3127+
return ResolveResult(resolvedMemberType,
3128+
nestedPA->getOrCreateEquivalenceClass());
30813129
}
30823130

3131+
return ResolveResult::forUnresolved(nullptr);
3132+
}
3133+
3134+
EquivalenceClass *GenericSignatureBuilder::resolveEquivalenceClass(
3135+
Type type,
3136+
ArchetypeResolutionKind resolutionKind) {
3137+
if (auto resolved = maybeResolveEquivalenceClass(type, resolutionKind))
3138+
return resolved.getEquivalenceClass();
3139+
30833140
return nullptr;
30843141
}
30853142

@@ -3134,7 +3191,7 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
31343191
Type resolved =
31353192
resolveDependentMemberTypes(*this, type, resolutionKind);
31363193
if (resolved->hasError() && !type->hasError())
3137-
return static_cast<EquivalenceClass *>(nullptr);
3194+
return ResolveResult::forUnresolved(nullptr);
31383195

31393196
type = resolved;
31403197
}
@@ -3146,7 +3203,9 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
31463203
// fails, it's because we weren't allowed to resolve anything now.
31473204
auto resolved = resolvePotentialArchetype(type, resolutionKind);
31483205
pa = resolved.dyn_cast<PotentialArchetype *>();
3149-
if (!pa) return resolved.get<EquivalenceClass *>();
3206+
if (!pa) {
3207+
return ResolveResult::forUnresolved(resolved.get<EquivalenceClass *>());
3208+
}
31503209
}
31513210

31523211
return ResolveResult(pa);

0 commit comments

Comments
 (0)