@@ -2115,30 +2115,28 @@ static bool isMainDispatchQueueMember(ConstraintLocator *locator) {
21152115}
21162116
21172117// / 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.
21202120// /
21212121// / \note If a 'Self'-rooted type parameter is bound to a concrete type, this
21222122// / routine will recurse into the concrete type.
21232123static 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) {
21252130 assert (baseTy->isExistentialType ());
2126- if (!refTy-> hasTypeParameter ()) {
2131+ if (!containsFn (refTy))
21272132 return refTy;
2128- }
2129-
2130- const auto existentialSig =
2131- baseTy->getASTContext ().getOpenedExistentialSignature (baseTy,
2132- GenericSignature ());
2133-
2134- unsigned metatypeDepth = 0 ;
21352133
21362134 std::function<Type (Type, TypePosition)> transformFn;
21372135 transformFn = [&](Type type, TypePosition initialPos) -> Type {
21382136 return type.transformWithPosition (
21392137 initialPos,
21402138 [&](TypeBase *t, TypePosition currPos) -> llvm::Optional<Type> {
2141- if (!t-> hasTypeParameter ( )) {
2139+ if (!containsFn (t )) {
21422140 return Type (t);
21432141 }
21442142
@@ -2160,9 +2158,10 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
21602158 if (auto opaque = dyn_cast<OpaqueTypeArchetypeType>(t)) {
21612159 for (auto replacementType :
21622160 opaque->getSubstitutions ().getReplacementTypes ()) {
2163- if (replacementType->hasTypeParameter ()) {
2161+ auto erasedReplacementType = transformFn (replacementType,
2162+ TypePosition::Covariant);
2163+ if (erasedReplacementType.getPointer () != replacementType.getPointer ())
21642164 return opaque->getExistentialType ();
2165- }
21662165 }
21672166 }
21682167
@@ -2175,21 +2174,31 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
21752174 return erased;
21762175 }
21772176
2178- if (!t-> isTypeParameter ( )) {
2177+ if (!predicateFn (t )) {
21792178 // Recurse.
21802179 return llvm::None;
21812180 }
21822181
2183- assert (t->getRootGenericParam ()->getDepth () == 0 );
2182+ auto paramTy = projectionFn (t);
2183+ if (!paramTy)
2184+ return Type (t);
21842185
21852186 // This can happen with invalid code.
2186- if (!existentialSig->isValidTypeParameter (t )) {
2187+ if (!existentialSig->isValidTypeParameter (paramTy )) {
21872188 return Type (t);
21882189 }
21892190
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);
21932202 if (erasedTy.getPointer () == concreteTy.getPointer ()) {
21942203 // Don't return the concrete type if we haven't type-erased
21952204 // anything inside it, or else we might inadvertently transform a
@@ -2200,23 +2209,25 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
22002209 return erasedTy;
22012210 }
22022211
2203- switch (currPos) {
2204- case TypePosition::Covariant:
2205- break ;
2212+ if (!force) {
2213+ switch (currPos) {
2214+ case TypePosition::Covariant:
2215+ break ;
22062216
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+ }
22112222 }
22122223
22132224 Type erasedTy;
22142225
22152226 // The upper bounds of 'Self' is the existential base type.
2216- if (t ->is <GenericTypeParamType>()) {
2227+ if (paramTy ->is <GenericTypeParamType>()) {
22172228 erasedTy = baseTy;
22182229 } else {
2219- erasedTy = existentialSig->getUpperBound (t );
2230+ erasedTy = existentialSig->getUpperBound (paramTy );
22202231 }
22212232
22222233 if (metatypeDepth) {
@@ -2233,117 +2244,61 @@ static Type typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
22332244Type constraints::typeEraseOpenedExistentialReference (
22342245 Type type, Type existentialBaseType, TypeVariableType *openedTypeVar,
22352246 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+ });
22602269
2261- if (isa<GenericTypeParamType>(t) && t-> isEqual (selfGP) )
2262- return Type (openedTypeVar );
2270+ if (!found )
2271+ return Type ();
22632272
2264- // Recurse.
2265- return llvm::None;
2266- });
2273+ assert (result->isTypeParameter ());
2274+ return result;
2275+ },
2276+ /* force=*/ false );
22672277}
22682278
22692279Type constraints::typeEraseOpenedArchetypesWithRoot (
22702280 Type type, const OpenedArchetypeType *root) {
22712281 assert (root->isRoot () && " Expected a root archetype" );
22722282
2273- if (!type->hasOpenedExistential ())
2274- return type;
2275-
22762283 auto *env = root->getGenericEnvironment ();
22772284 auto sig = env->getGenericSignature ();
22782285
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 ();
23452298
2346- return transformFn (type);
2299+ return Type ();
2300+ },
2301+ /* force=*/ true );
23472302}
23482303
23492304Type ConstraintSystem::getMemberReferenceTypeFromOpenedType (
0 commit comments