@@ -2115,30 +2115,28 @@ static bool isMainDispatchQueueMember(ConstraintLocator *locator) {
2115
2115
}
2116
2116
2117
2117
// / Type-erase occurrences of covariant 'Self'-rooted type parameters to their
2118
- // / most specific non-dependent bounds throughout the given type, using
2119
- // / \p baseTy as the existential base object type.
2118
+ // / most specific upper bounds throughout the given type, using \p baseTy as
2119
+ // / the existential base object type.
2120
2120
// /
2121
2121
// / \note If a 'Self'-rooted type parameter is bound to a concrete type, this
2122
2122
// / routine will recurse into the concrete type.
2123
2123
static Type typeEraseExistentialSelfReferences (Type refTy, Type baseTy,
2124
- TypePosition outermostPosition) {
2124
+ TypePosition outermostPosition,
2125
+ GenericSignature existentialSig,
2126
+ llvm::function_ref<bool (Type)> containsFn,
2127
+ llvm::function_ref<bool(Type)> predicateFn,
2128
+ llvm::function_ref<Type(Type)> projectionFn,
2129
+ bool force, unsigned metatypeDepth = 0) {
2125
2130
assert (baseTy->isExistentialType ());
2126
- if (!refTy-> hasTypeParameter ()) {
2131
+ if (!containsFn (refTy))
2127
2132
return refTy;
2128
- }
2129
-
2130
- const auto existentialSig =
2131
- baseTy->getASTContext ().getOpenedExistentialSignature (baseTy,
2132
- GenericSignature ());
2133
-
2134
- unsigned metatypeDepth = 0 ;
2135
2133
2136
2134
std::function<Type (Type, TypePosition)> transformFn;
2137
2135
transformFn = [&](Type type, TypePosition initialPos) -> Type {
2138
2136
return type.transformWithPosition (
2139
2137
initialPos,
2140
2138
[&](TypeBase *t, TypePosition currPos) -> llvm::Optional<Type> {
2141
- if (!t-> hasTypeParameter ( )) {
2139
+ if (!containsFn (t )) {
2142
2140
return Type (t);
2143
2141
}
2144
2142
@@ -2160,9 +2158,10 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
2160
2158
if (auto opaque = dyn_cast<OpaqueTypeArchetypeType>(t)) {
2161
2159
for (auto replacementType :
2162
2160
opaque->getSubstitutions ().getReplacementTypes ()) {
2163
- if (replacementType->hasTypeParameter ()) {
2161
+ auto erasedReplacementType = transformFn (replacementType,
2162
+ TypePosition::Covariant);
2163
+ if (erasedReplacementType.getPointer () != replacementType.getPointer ())
2164
2164
return opaque->getExistentialType ();
2165
- }
2166
2165
}
2167
2166
}
2168
2167
@@ -2175,21 +2174,31 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
2175
2174
return erased;
2176
2175
}
2177
2176
2178
- if (!t-> isTypeParameter ( )) {
2177
+ if (!predicateFn (t )) {
2179
2178
// Recurse.
2180
2179
return llvm::None;
2181
2180
}
2182
2181
2183
- assert (t->getRootGenericParam ()->getDepth () == 0 );
2182
+ auto paramTy = projectionFn (t);
2183
+ if (!paramTy)
2184
+ return Type (t);
2184
2185
2185
2186
// This can happen with invalid code.
2186
- if (!existentialSig->isValidTypeParameter (t )) {
2187
+ if (!existentialSig->isValidTypeParameter (paramTy )) {
2187
2188
return Type (t);
2188
2189
}
2189
2190
2190
- // If the type parameter is bound to a concrete type, recurse into it.
2191
- if (const auto concreteTy = existentialSig->getConcreteType (t)) {
2192
- const auto erasedTy = transformFn (concreteTy, currPos);
2191
+ // If the type parameter is fixed to a concrete type, recurse into it.
2192
+ if (const auto concreteTy = existentialSig->getConcreteType (paramTy)) {
2193
+ auto erasedTy = typeEraseExistentialSelfReferences (
2194
+ concreteTy, baseTy, currPos, existentialSig,
2195
+ [](Type t) { return t->hasTypeParameter (); },
2196
+ [](Type t) { return t->isTypeParameter (); },
2197
+ [](Type t) {
2198
+ assert (t->isTypeParameter ());
2199
+ return t;
2200
+ },
2201
+ metatypeDepth);
2193
2202
if (erasedTy.getPointer () == concreteTy.getPointer ()) {
2194
2203
// Don't return the concrete type if we haven't type-erased
2195
2204
// anything inside it, or else we might inadvertently transform a
@@ -2200,23 +2209,25 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
2200
2209
return erasedTy;
2201
2210
}
2202
2211
2203
- switch (currPos) {
2204
- case TypePosition::Covariant:
2205
- break ;
2212
+ if (!force) {
2213
+ switch (currPos) {
2214
+ case TypePosition::Covariant:
2215
+ break ;
2206
2216
2207
- case TypePosition::Contravariant:
2208
- case TypePosition::Invariant:
2209
- case TypePosition::Shape:
2210
- return Type (t);
2217
+ case TypePosition::Contravariant:
2218
+ case TypePosition::Invariant:
2219
+ case TypePosition::Shape:
2220
+ return Type (t);
2221
+ }
2211
2222
}
2212
2223
2213
2224
Type erasedTy;
2214
2225
2215
2226
// The upper bounds of 'Self' is the existential base type.
2216
- if (t ->is <GenericTypeParamType>()) {
2227
+ if (paramTy ->is <GenericTypeParamType>()) {
2217
2228
erasedTy = baseTy;
2218
2229
} else {
2219
- erasedTy = existentialSig->getUpperBound (t );
2230
+ erasedTy = existentialSig->getUpperBound (paramTy );
2220
2231
}
2221
2232
2222
2233
if (metatypeDepth) {
@@ -2233,117 +2244,61 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
2233
2244
Type constraints::typeEraseOpenedExistentialReference (
2234
2245
Type type, Type existentialBaseType, TypeVariableType *openedTypeVar,
2235
2246
TypePosition outermostPosition) {
2236
- Type selfGP = GenericTypeParamType::get (false , 0 , 0 , type->getASTContext ());
2237
-
2238
- // First, temporarily reconstitute the 'Self' generic parameter.
2239
- type = type.transformRec ([&](TypeBase *t) -> llvm::Optional<Type> {
2240
- // Don't recurse into children unless we have to.
2241
- if (!type->hasTypeVariable ())
2242
- return Type (t);
2243
-
2244
- if (isa<TypeVariableType>(t) && t->isEqual (openedTypeVar))
2245
- return selfGP;
2246
-
2247
- // Recurse.
2248
- return llvm::None;
2249
- });
2250
-
2251
- // Then, type-erase occurrences of covariant 'Self'-rooted type parameters.
2252
- type = typeEraseExistentialSelfReferences (type, existentialBaseType,
2253
- outermostPosition);
2254
-
2255
- // Finally, swap the 'Self'-corresponding type variable back in.
2256
- return type.transformRec ([&](TypeBase *t) -> llvm::Optional<Type> {
2257
- // Don't recurse into children unless we have to.
2258
- if (!type->hasTypeParameter ())
2259
- return Type (t);
2247
+ auto existentialSig =
2248
+ type->getASTContext ().getOpenedExistentialSignature (
2249
+ existentialBaseType, GenericSignature ());
2250
+ auto selfGP = existentialSig.getGenericParams ()[0 ];
2251
+
2252
+ return typeEraseExistentialSelfReferences (
2253
+ type, existentialBaseType, outermostPosition, existentialSig,
2254
+ /* containsFn=*/ [](Type t) {
2255
+ return t->hasTypeVariable ();
2256
+ },
2257
+ /* predicateFn=*/ [](Type t) {
2258
+ return t->isTypeVariableOrMember ();
2259
+ },
2260
+ /* projectionFn=*/ [&](Type t) {
2261
+ bool found = false ;
2262
+ auto result = t.transformRec ([&](Type t) -> llvm::Optional<Type> {
2263
+ if (t.getPointer () == openedTypeVar) {
2264
+ found = true ;
2265
+ return selfGP;
2266
+ }
2267
+ return llvm::None;
2268
+ });
2260
2269
2261
- if (isa<GenericTypeParamType>(t) && t-> isEqual (selfGP) )
2262
- return Type (openedTypeVar );
2270
+ if (!found )
2271
+ return Type ();
2263
2272
2264
- // Recurse.
2265
- return llvm::None;
2266
- });
2273
+ assert (result->isTypeParameter ());
2274
+ return result;
2275
+ },
2276
+ /* force=*/ false );
2267
2277
}
2268
2278
2269
2279
Type constraints::typeEraseOpenedArchetypesWithRoot (
2270
2280
Type type, const OpenedArchetypeType *root) {
2271
2281
assert (root->isRoot () && " Expected a root archetype" );
2272
2282
2273
- if (!type->hasOpenedExistential ())
2274
- return type;
2275
-
2276
2283
auto *env = root->getGenericEnvironment ();
2277
2284
auto sig = env->getGenericSignature ();
2278
2285
2279
- unsigned metatypeDepth = 0 ;
2280
-
2281
- std::function<Type (Type)> transformFn;
2282
- transformFn = [&](Type type) -> Type {
2283
- return type.transformRec ([&](TypeBase *ty) -> llvm::Optional<Type> {
2284
- // Don't recurse into children unless we have to.
2285
- if (!ty->hasOpenedExistential ())
2286
- return Type (ty);
2287
-
2288
- if (isa<MetatypeType>(ty)) {
2289
- const auto instanceTy = ty->getMetatypeInstanceType ();
2290
- ++metatypeDepth;
2291
- const auto erasedTy = transformFn (instanceTy);
2292
- --metatypeDepth;
2293
-
2294
- if (instanceTy.getPointer () == erasedTy.getPointer ()) {
2295
- return Type (ty);
2296
- }
2297
-
2298
- return Type (ExistentialMetatypeType::get (erasedTy));
2299
- }
2300
-
2301
- // Opaque types whose substitutions involve this type parameter are
2302
- // erased to their upper bound.
2303
- if (auto opaque = dyn_cast<OpaqueTypeArchetypeType>(ty)) {
2304
- for (auto replacementType :
2305
- opaque->getSubstitutions ().getReplacementTypes ()) {
2306
- if (replacementType->hasOpenedExistentialWithRoot (root)) {
2307
- return opaque->getExistentialType ();
2308
- }
2309
- }
2310
- }
2311
-
2312
- if (auto lvalue = dyn_cast<LValueType>(type)) {
2313
- auto objTy = lvalue->getObjectType ();
2314
- auto erased = transformFn (objTy);
2315
- if (erased.getPointer () == objTy.getPointer ())
2316
- return Type (lvalue);
2317
-
2318
- return erased;
2319
- }
2320
-
2321
- auto *const archetype = dyn_cast<OpenedArchetypeType>(ty);
2322
- if (!archetype) {
2323
- // Recurse.
2324
- return llvm::None;
2325
- }
2326
-
2327
- if (archetype->getGenericEnvironment () != env)
2328
- return Type (ty);
2329
-
2330
- Type erasedTy;
2331
- if (root->isEqual (archetype)) {
2332
- erasedTy = root->getExistentialType ();
2333
- } else {
2334
- erasedTy = sig->getUpperBound (archetype->getInterfaceType ());
2335
- }
2336
-
2337
- if (metatypeDepth) {
2338
- if (const auto existential = erasedTy->getAs <ExistentialType>())
2339
- return existential->getConstraintType ();
2340
- }
2341
-
2342
- return erasedTy;
2343
- });
2344
- };
2286
+ return typeEraseExistentialSelfReferences (
2287
+ type, root->getExistentialType (), TypePosition::Covariant, sig,
2288
+ /* containsFn=*/ [](Type t) {
2289
+ return t->hasOpenedExistential ();
2290
+ },
2291
+ /* predicateFn=*/ [](Type t) {
2292
+ return t->is <OpenedArchetypeType>();
2293
+ },
2294
+ /* projectionFn=*/ [&](Type t) {
2295
+ auto *openedTy = t->castTo <OpenedArchetypeType>();
2296
+ if (openedTy->getGenericEnvironment () == env)
2297
+ return openedTy->getInterfaceType ();
2345
2298
2346
- return transformFn (type);
2299
+ return Type ();
2300
+ },
2301
+ /* force=*/ true );
2347
2302
}
2348
2303
2349
2304
Type ConstraintSystem::getMemberReferenceTypeFromOpenedType (
0 commit comments