mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Constraint System] Fix covariant erasure for constrained existentials
Constrained existentials should be type erased to an upper bound that is dependent on other type parameters.
This commit is contained in:
@@ -2054,9 +2054,9 @@ static bool isMainDispatchQueueMember(ConstraintLocator *locator) {
|
||||
/// \note If a 'Self'-rooted type parameter is bound to a concrete type, this
|
||||
/// routine will recurse into the concrete type.
|
||||
static Type
|
||||
typeEraseExistentialSelfReferences(
|
||||
Type refTy, Type baseTy,
|
||||
TypePosition outermostPosition) {
|
||||
typeEraseExistentialSelfReferences(Type refTy, Type baseTy,
|
||||
TypePosition outermostPosition,
|
||||
bool wantNonDependentBound = true) {
|
||||
assert(baseTy->isExistentialType());
|
||||
if (!refTy->hasTypeParameter()) {
|
||||
return refTy;
|
||||
@@ -2159,7 +2159,9 @@ typeEraseExistentialSelfReferences(
|
||||
if (t->is<GenericTypeParamType>()) {
|
||||
erasedTy = baseTy;
|
||||
} else {
|
||||
erasedTy = existentialSig->getNonDependentUpperBounds(t);
|
||||
erasedTy = wantNonDependentBound
|
||||
? existentialSig->getNonDependentUpperBounds(t)
|
||||
: existentialSig->getDependentUpperBounds(t);
|
||||
}
|
||||
|
||||
if (metatypeDepth) {
|
||||
@@ -2170,13 +2172,12 @@ typeEraseExistentialSelfReferences(
|
||||
return erasedTy;
|
||||
});
|
||||
};
|
||||
|
||||
return transformFn(refTy, outermostPosition);
|
||||
}
|
||||
|
||||
Type constraints::typeEraseOpenedExistentialReference(
|
||||
Type type, Type existentialBaseType, TypeVariableType *openedTypeVar,
|
||||
TypePosition outermostPosition) {
|
||||
TypePosition outermostPosition, bool wantNonDependentBound) {
|
||||
Type selfGP = GenericTypeParamType::get(false, 0, 0, type->getASTContext());
|
||||
|
||||
// First, temporarily reconstitute the 'Self' generic parameter.
|
||||
@@ -2193,8 +2194,8 @@ Type constraints::typeEraseOpenedExistentialReference(
|
||||
});
|
||||
|
||||
// Then, type-erase occurrences of covariant 'Self'-rooted type parameters.
|
||||
type = typeEraseExistentialSelfReferences(type, existentialBaseType,
|
||||
outermostPosition);
|
||||
type = typeEraseExistentialSelfReferences(
|
||||
type, existentialBaseType, outermostPosition, wantNonDependentBound);
|
||||
|
||||
// Finally, swap the 'Self'-corresponding type variable back in.
|
||||
return type.transformRec([&](TypeBase *t) -> Optional<Type> {
|
||||
@@ -2299,16 +2300,25 @@ Type ConstraintSystem::getMemberReferenceTypeFromOpenedType(
|
||||
const auto selfGP = cast<GenericTypeParamType>(
|
||||
outerDC->getSelfInterfaceType()->getCanonicalType());
|
||||
auto openedTypeVar = replacements.lookup(selfGP);
|
||||
|
||||
type = typeEraseOpenedExistentialReference(type, baseObjTy, openedTypeVar,
|
||||
TypePosition::Covariant);
|
||||
|
||||
Type contextualTy;
|
||||
|
||||
if (auto *anchor = getAsExpr(simplifyLocatorToAnchor(locator))) {
|
||||
contextualTy =
|
||||
getContextualType(getParentExpr(anchor), /*forConstraint=*/false);
|
||||
}
|
||||
|
||||
if (!hasFixFor(locator) &&
|
||||
AddExplicitExistentialCoercion::isRequired(
|
||||
*this, nonErasedResultTy,
|
||||
[&](TypeVariableType *typeVar) {
|
||||
return openedTypeVar == typeVar ? baseObjTy : Optional<Type>();
|
||||
},
|
||||
locator)) {
|
||||
locator) &&
|
||||
!contextualTy) {
|
||||
recordFix(AddExplicitExistentialCoercion::create(
|
||||
*this, getResultType(type), locator));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user