@@ -2131,114 +2131,117 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
21312131 if (!containsFn (refTy))
21322132 return refTy;
21332133
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+ }
21422140
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 );
21482148
2149- if (instanceTy.getPointer () == erasedTy.getPointer ()) {
2150- return Type (t);
2151- }
2149+ if (instanceTy.getPointer () == erasedTy.getPointer ()) {
2150+ return Type (t);
2151+ }
21522152
2153- return Type (ExistentialMetatypeType::get (erasedTy));
2154- }
2153+ return Type (ExistentialMetatypeType::get (erasedTy));
2154+ }
21552155
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+ }
21672170
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);
21732178
2174- return erased;
2175- }
2179+ if (erasedTy. getPointer () == objTy. getPointer ())
2180+ return Type (lvalue);
21762181
2177- if (!predicateFn (t)) {
2178- // Recurse.
2179- return llvm::None;
2180- }
2182+ return erasedTy;
2183+ }
21812184
2182- auto paramTy = projectionFn (t);
2183- if (!paramTy)
2184- return Type (t);
2185+ if (!predicateFn (t)) {
2186+ // Recurse.
2187+ return llvm::None;
2188+ }
21852189
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);
21902193
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+ }
22082198
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+ }
22112213
2212- if (!force) {
2213- switch (currPos) {
2214- case TypePosition::Covariant:
2215- break ;
2214+ return erasedTy;
2215+ }
22162216
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 ;
22232221
2224- Type erasedTy;
2222+ case TypePosition::Contravariant:
2223+ case TypePosition::Invariant:
2224+ case TypePosition::Shape:
2225+ return Type (t);
2226+ }
2227+ }
22252228
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;
22322230
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+ }
22372237
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+ });
22422245}
22432246
22442247Type constraints::typeEraseOpenedExistentialReference (
0 commit comments