@@ -2131,114 +2131,117 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
2131
2131
if (!containsFn (refTy))
2132
2132
return refTy;
2133
2133
2134
- std::function<Type (Type, TypePosition)> transformFn;
2135
- transformFn = [&](Type type, TypePosition initialPos) -> Type {
2136
- return type.transformWithPosition (
2137
- initialPos,
2138
- [&](TypeBase *t, TypePosition currPos) -> llvm::Optional<Type> {
2139
- if (!containsFn (t)) {
2140
- return Type (t);
2141
- }
2134
+ return refTy.transformWithPosition (
2135
+ outermostPosition,
2136
+ [&](TypeBase *t, TypePosition currPos) -> llvm::Optional<Type> {
2137
+ if (!containsFn (t)) {
2138
+ return Type (t);
2139
+ }
2142
2140
2143
- if (t->is <MetatypeType>()) {
2144
- const auto instanceTy = t->getMetatypeInstanceType ();
2145
- ++metatypeDepth;
2146
- const auto erasedTy = transformFn (instanceTy, currPos);
2147
- --metatypeDepth;
2141
+ if (t->is <MetatypeType>()) {
2142
+ const auto instanceTy = t->getMetatypeInstanceType ();
2143
+ const auto erasedTy =
2144
+ typeEraseExistentialSelfReferences (
2145
+ instanceTy, baseTy, currPos,
2146
+ existentialSig, containsFn, predicateFn, projectionFn,
2147
+ force, metatypeDepth + 1 );
2148
2148
2149
- if (instanceTy.getPointer () == erasedTy.getPointer ()) {
2150
- return Type (t);
2151
- }
2149
+ if (instanceTy.getPointer () == erasedTy.getPointer ()) {
2150
+ return Type (t);
2151
+ }
2152
2152
2153
- return Type (ExistentialMetatypeType::get (erasedTy));
2154
- }
2153
+ return Type (ExistentialMetatypeType::get (erasedTy));
2154
+ }
2155
2155
2156
- // Opaque types whose substitutions involve this type parameter are
2157
- // erased to their upper bound.
2158
- if (auto opaque = dyn_cast<OpaqueTypeArchetypeType>(t)) {
2159
- for (auto replacementType :
2160
- opaque->getSubstitutions ().getReplacementTypes ()) {
2161
- auto erasedReplacementType = transformFn (replacementType,
2162
- TypePosition::Covariant);
2163
- if (erasedReplacementType.getPointer () != replacementType.getPointer ())
2164
- return opaque->getExistentialType ();
2165
- }
2166
- }
2156
+ // Opaque types whose substitutions involve this type parameter are
2157
+ // erased to their upper bound.
2158
+ if (auto opaque = dyn_cast<OpaqueTypeArchetypeType>(t)) {
2159
+ for (auto replacementType :
2160
+ opaque->getSubstitutions ().getReplacementTypes ()) {
2161
+ auto erasedReplacementType =
2162
+ typeEraseExistentialSelfReferences (
2163
+ replacementType, baseTy, TypePosition::Covariant,
2164
+ existentialSig, containsFn, predicateFn, projectionFn,
2165
+ force, metatypeDepth);
2166
+ if (erasedReplacementType.getPointer () != replacementType.getPointer ())
2167
+ return opaque->getExistentialType ();
2168
+ }
2169
+ }
2167
2170
2168
- if (auto lvalue = dyn_cast<LValueType>(t)) {
2169
- auto objTy = lvalue->getObjectType ();
2170
- auto erased = transformFn (objTy, currPos);
2171
- if (erased.getPointer () == objTy.getPointer ())
2172
- return Type (lvalue);
2171
+ if (auto lvalue = dyn_cast<LValueType>(t)) {
2172
+ auto objTy = lvalue->getObjectType ();
2173
+ auto erasedTy =
2174
+ typeEraseExistentialSelfReferences (
2175
+ objTy, baseTy, currPos,
2176
+ existentialSig, containsFn, predicateFn, projectionFn,
2177
+ force, metatypeDepth);
2173
2178
2174
- return erased;
2175
- }
2179
+ if (erasedTy. getPointer () == objTy. getPointer ())
2180
+ return Type (lvalue);
2176
2181
2177
- if (!predicateFn (t)) {
2178
- // Recurse.
2179
- return llvm::None;
2180
- }
2182
+ return erasedTy;
2183
+ }
2181
2184
2182
- auto paramTy = projectionFn (t);
2183
- if (!paramTy)
2184
- return Type (t);
2185
+ if (!predicateFn (t)) {
2186
+ // Recurse.
2187
+ return llvm::None;
2188
+ }
2185
2189
2186
- // This can happen with invalid code.
2187
- if (!existentialSig->isValidTypeParameter (paramTy)) {
2188
- return Type (t);
2189
- }
2190
+ auto paramTy = projectionFn (t);
2191
+ if (!paramTy)
2192
+ return Type (t);
2190
2193
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);
2202
- if (erasedTy.getPointer () == concreteTy.getPointer ()) {
2203
- // Don't return the concrete type if we haven't type-erased
2204
- // anything inside it, or else we might inadvertently transform a
2205
- // normal metatype into an existential one.
2206
- return Type (t);
2207
- }
2194
+ // This can happen with invalid code.
2195
+ if (!existentialSig->isValidTypeParameter (paramTy)) {
2196
+ return Type (t);
2197
+ }
2208
2198
2209
- return erasedTy;
2210
- }
2199
+ // If the type parameter is fixed to a concrete type, recurse into it.
2200
+ if (const auto concreteTy = existentialSig->getConcreteType (paramTy)) {
2201
+ auto erasedTy = typeEraseExistentialSelfReferences (
2202
+ concreteTy, baseTy, currPos, existentialSig,
2203
+ [](Type t) { return t->hasTypeParameter (); },
2204
+ [](Type t) { return t->isTypeParameter (); },
2205
+ [](Type t) { return t; },
2206
+ force, metatypeDepth);
2207
+ if (erasedTy.getPointer () == concreteTy.getPointer ()) {
2208
+ // Don't return the concrete type if we haven't type-erased
2209
+ // anything inside it, or else we might inadvertently transform a
2210
+ // normal metatype into an existential one.
2211
+ return Type (t);
2212
+ }
2211
2213
2212
- if (!force) {
2213
- switch (currPos) {
2214
- case TypePosition::Covariant:
2215
- break ;
2214
+ return erasedTy;
2215
+ }
2216
2216
2217
- case TypePosition::Contravariant:
2218
- case TypePosition::Invariant:
2219
- case TypePosition::Shape:
2220
- return Type (t);
2221
- }
2222
- }
2217
+ if (!force) {
2218
+ switch (currPos) {
2219
+ case TypePosition::Covariant:
2220
+ break ;
2223
2221
2224
- Type erasedTy;
2222
+ case TypePosition::Contravariant:
2223
+ case TypePosition::Invariant:
2224
+ case TypePosition::Shape:
2225
+ return Type (t);
2226
+ }
2227
+ }
2225
2228
2226
- // The upper bounds of 'Self' is the existential base type.
2227
- if (paramTy->is <GenericTypeParamType>()) {
2228
- erasedTy = baseTy;
2229
- } else {
2230
- erasedTy = existentialSig->getUpperBound (paramTy);
2231
- }
2229
+ Type erasedTy;
2232
2230
2233
- if (metatypeDepth) {
2234
- if (const auto existential = erasedTy->getAs <ExistentialType>())
2235
- return existential->getConstraintType ();
2236
- }
2231
+ // The upper bounds of 'Self' is the existential base type.
2232
+ if (paramTy->is <GenericTypeParamType>()) {
2233
+ erasedTy = baseTy;
2234
+ } else {
2235
+ erasedTy = existentialSig->getUpperBound (paramTy);
2236
+ }
2237
2237
2238
- return erasedTy;
2239
- });
2240
- };
2241
- return transformFn (refTy, outermostPosition);
2238
+ if (metatypeDepth) {
2239
+ if (const auto existential = erasedTy->getAs <ExistentialType>())
2240
+ return existential->getConstraintType ();
2241
+ }
2242
+
2243
+ return erasedTy;
2244
+ });
2242
2245
}
2243
2246
2244
2247
Type constraints::typeEraseOpenedExistentialReference (
0 commit comments