@@ -2209,6 +2209,11 @@ class GenericSignatureBuilder::ResolveResult {
2209
2209
llvm::PointerUnion<Type, PotentialArchetype *> type;
2210
2210
EquivalenceClass *equivClass;
2211
2211
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
+
2212
2217
public:
2213
2218
// / A specific resolved potential archetype.
2214
2219
ResolveResult (PotentialArchetype *pa)
@@ -2221,17 +2226,26 @@ class GenericSignatureBuilder::ResolveResult {
2221
2226
" type parameters must have equivalence classes" );
2222
2227
}
2223
2228
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
+ }
2228
2234
2229
2235
// / Determine whether this result was resolved.
2230
2236
explicit operator bool () const { return !type.isNull (); }
2231
2237
2232
2238
// / Retrieve the resolved type.
2233
2239
ResolvedType getResolvedType (GenericSignatureBuilder &builder) const ;
2234
2240
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
+
2235
2249
// / Retrieve the equivalence class into which a resolved type refers.
2236
2250
EquivalenceClass *getEquivalenceClass () const {
2237
2251
assert (*this && " Only for resolved types" );
@@ -2271,6 +2285,14 @@ ResolvedType ResolveResult::getResolvedType(
2271
2285
return ResolvedType::forPotentialArchetype (pa);
2272
2286
}
2273
2287
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
+
2274
2296
// / If there is a same-type requirement to be added for the given nested type
2275
2297
// / due to a superclass constraint on the parent type, add it now.
2276
2298
static void maybeAddSameTypeRequirementForNestedType (
@@ -3038,48 +3060,83 @@ auto GenericSignatureBuilder::resolvePotentialArchetype(
3038
3060
return (EquivalenceClass *)nullptr ;
3039
3061
}
3040
3062
3041
- EquivalenceClass * GenericSignatureBuilder::resolveEquivalenceClass (
3063
+ ResolveResult GenericSignatureBuilder::maybeResolveEquivalenceClass (
3042
3064
Type type,
3043
3065
ArchetypeResolutionKind resolutionKind) {
3044
3066
// The equivalence class of a generic type is known directly.
3045
3067
if (auto genericParam = type->getAs <GenericTypeParamType>()) {
3046
3068
unsigned index = GenericParamKey (genericParam).findIndexIn (
3047
3069
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
+ }
3050
3074
3051
- return nullptr ;
3075
+ return ResolveResult::forUnresolved ( nullptr ) ;
3052
3076
}
3053
3077
3054
3078
// The equivalence class of a dependent member type is determined by its
3055
3079
// base equivalence class.
3056
3080
if (auto depMemTy = type->getAs <DependentMemberType>()) {
3057
3081
// 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 ;
3061
3085
3062
3086
// Find the nested type declaration for this.
3087
+ auto baseEquivClass = resolvedBase.getEquivalenceClass ();
3063
3088
TypeDecl *nestedTypeDecl;
3064
3089
if (auto assocType = depMemTy->getAssocType ()) {
3065
3090
nestedTypeDecl = assocType;
3066
3091
} else {
3067
3092
nestedTypeDecl = baseEquivClass->lookupNestedType (depMemTy->getName ());
3068
- if (!nestedTypeDecl) return nullptr ;
3093
+ if (!nestedTypeDecl) {
3094
+ return ResolveResult::forUnresolved (baseEquivClass);
3095
+ }
3069
3096
}
3070
3097
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.
3072
3101
auto baseAnchorPA =
3073
3102
baseEquivClass->members .front ()->getArchetypeAnchor (*this );
3074
3103
auto nestedPA =
3075
3104
baseAnchorPA->updateNestedTypeForConformance (nestedTypeDecl,
3076
3105
resolutionKind);
3077
3106
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
+ }
3079
3126
3080
- return nestedPA->getOrCreateEquivalenceClass ();
3127
+ return ResolveResult (resolvedMemberType,
3128
+ nestedPA->getOrCreateEquivalenceClass ());
3081
3129
}
3082
3130
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
+
3083
3140
return nullptr ;
3084
3141
}
3085
3142
@@ -3134,7 +3191,7 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
3134
3191
Type resolved =
3135
3192
resolveDependentMemberTypes (*this , type, resolutionKind);
3136
3193
if (resolved->hasError () && !type->hasError ())
3137
- return static_cast <EquivalenceClass *> (nullptr );
3194
+ return ResolveResult::forUnresolved (nullptr );
3138
3195
3139
3196
type = resolved;
3140
3197
}
@@ -3146,7 +3203,9 @@ auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
3146
3203
// fails, it's because we weren't allowed to resolve anything now.
3147
3204
auto resolved = resolvePotentialArchetype (type, resolutionKind);
3148
3205
pa = resolved.dyn_cast <PotentialArchetype *>();
3149
- if (!pa) return resolved.get <EquivalenceClass *>();
3206
+ if (!pa) {
3207
+ return ResolveResult::forUnresolved (resolved.get <EquivalenceClass *>());
3208
+ }
3150
3209
}
3151
3210
3152
3211
return ResolveResult (pa);
0 commit comments