mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[TypeChecker] Require a coercion if result of protocol member access would loose information
Accessing members on the protocol could result in existential opening and subsequence result erasure, which requires explicit coercion if there is any loss of generic requirements.
This commit is contained in:
@@ -2296,11 +2296,30 @@ ConstraintSystem::getTypeOfMemberReference(
|
||||
baseObjTy->isExistentialType() && outerDC->getSelfProtocolDecl() &&
|
||||
// If there are no type variables, there were no references to 'Self'.
|
||||
type->hasTypeVariable()) {
|
||||
auto getResultType = [](Type type) {
|
||||
if (auto *funcTy = type->getAs<FunctionType>())
|
||||
return funcTy->getResult();
|
||||
return type;
|
||||
};
|
||||
|
||||
auto nonErasedResultTy = getResultType(type);
|
||||
|
||||
const auto selfGP = cast<GenericTypeParamType>(
|
||||
outerDC->getSelfInterfaceType()->getCanonicalType());
|
||||
auto openedTypeVar = replacements.lookup(selfGP);
|
||||
type = typeEraseOpenedExistentialReference(type, baseObjTy, openedTypeVar,
|
||||
TypePosition::Covariant);
|
||||
|
||||
if (!hasFixFor(locator) &&
|
||||
AddExplicitExistentialCoercion::isRequired(
|
||||
*this, nonErasedResultTy,
|
||||
[&](TypeVariableType *typeVar) {
|
||||
return openedTypeVar == typeVar ? baseObjTy : Optional<Type>();
|
||||
},
|
||||
locator)) {
|
||||
recordFix(AddExplicitExistentialCoercion::create(
|
||||
*this, getResultType(type), locator));
|
||||
}
|
||||
}
|
||||
|
||||
// Construct an idealized parameter type of the initializer associated
|
||||
|
||||
Reference in New Issue
Block a user