mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Merge the two implementations of simplifyType()
ConstraintSystem::simplifyType() replaced types with their fixed types from the global map. Solution::simplifyType() replaced types with their fixed types from the current bindings. There were some minor differences between the two, and some dead code.
This commit is contained in:
@@ -85,7 +85,7 @@ Type Solution::computeSubstitutions(
|
|||||||
auto &tc = getConstraintSystem().getTypeChecker();
|
auto &tc = getConstraintSystem().getTypeChecker();
|
||||||
|
|
||||||
// Produce the concrete form of the opened type.
|
// Produce the concrete form of the opened type.
|
||||||
Type type = simplifyType(tc, openedType);
|
Type type = simplifyType(openedType);
|
||||||
|
|
||||||
// Gather the substitutions from dependent types to concrete types.
|
// Gather the substitutions from dependent types to concrete types.
|
||||||
auto openedTypes = OpenedTypes.find(locator);
|
auto openedTypes = OpenedTypes.find(locator);
|
||||||
@@ -816,7 +816,7 @@ namespace {
|
|||||||
Type containerTy =
|
Type containerTy =
|
||||||
openedFullType->castTo<FunctionType>()
|
openedFullType->castTo<FunctionType>()
|
||||||
->getInput()->getRValueInstanceType();
|
->getInput()->getRValueInstanceType();
|
||||||
containerTy = solution.simplifyType(tc, containerTy);
|
containerTy = solution.simplifyType(containerTy);
|
||||||
|
|
||||||
// If we opened up an existential when referencing this member, update
|
// If we opened up an existential when referencing this member, update
|
||||||
// the base accordingly.
|
// the base accordingly.
|
||||||
@@ -1116,7 +1116,7 @@ namespace {
|
|||||||
/// \brief Simplify the given type by substituting all occurrences of
|
/// \brief Simplify the given type by substituting all occurrences of
|
||||||
/// type variables for their fixed types.
|
/// type variables for their fixed types.
|
||||||
Type simplifyType(Type type) {
|
Type simplifyType(Type type) {
|
||||||
return solution.simplifyType(cs.getTypeChecker(), type);
|
return solution.simplifyType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -1316,7 +1316,7 @@ namespace {
|
|||||||
// Convert the base.
|
// Convert the base.
|
||||||
auto openedFullFnType = selected->openedFullType->castTo<FunctionType>();
|
auto openedFullFnType = selected->openedFullType->castTo<FunctionType>();
|
||||||
auto openedBaseType = openedFullFnType->getInput();
|
auto openedBaseType = openedFullFnType->getInput();
|
||||||
containerTy = solution.simplifyType(tc, openedBaseType);
|
containerTy = solution.simplifyType(openedBaseType);
|
||||||
base = coerceObjectArgumentToType(
|
base = coerceObjectArgumentToType(
|
||||||
base, containerTy, subscript, AccessSemantics::Ordinary,
|
base, containerTy, subscript, AccessSemantics::Ordinary,
|
||||||
locator.withPathElement(ConstraintLocator::MemberRefBase));
|
locator.withPathElement(ConstraintLocator::MemberRefBase));
|
||||||
@@ -6890,7 +6890,7 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
|||||||
|
|
||||||
case FixKind::ForceOptional: {
|
case FixKind::ForceOptional: {
|
||||||
const Expr *unwrapped = affected->getValueProvidingExpr();
|
const Expr *unwrapped = affected->getValueProvidingExpr();
|
||||||
auto type = solution.simplifyType(TC, getType(affected))
|
auto type = solution.simplifyType(getType(affected))
|
||||||
->getRValueObjectType();
|
->getRValueObjectType();
|
||||||
|
|
||||||
if (auto tryExpr = dyn_cast<OptionalTryExpr>(unwrapped)) {
|
if (auto tryExpr = dyn_cast<OptionalTryExpr>(unwrapped)) {
|
||||||
@@ -6916,7 +6916,7 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case FixKind::OptionalChaining: {
|
case FixKind::OptionalChaining: {
|
||||||
auto type = solution.simplifyType(TC, getType(affected))
|
auto type = solution.simplifyType(getType(affected))
|
||||||
->getRValueObjectType();
|
->getRValueObjectType();
|
||||||
auto diag = TC.diagnose(affected->getLoc(),
|
auto diag = TC.diagnose(affected->getLoc(),
|
||||||
diag::missing_unwrap_optional, type);
|
diag::missing_unwrap_optional, type);
|
||||||
@@ -6925,10 +6925,9 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case FixKind::ForceDowncast: {
|
case FixKind::ForceDowncast: {
|
||||||
auto fromType = solution.simplifyType(TC, getType(affected))
|
auto fromType = solution.simplifyType(getType(affected))
|
||||||
->getRValueObjectType();
|
->getRValueObjectType();
|
||||||
Type toType = solution.simplifyType(TC,
|
Type toType = solution.simplifyType(fix.first.getTypeArgument(*this));
|
||||||
fix.first.getTypeArgument(*this));
|
|
||||||
bool useAs = TC.isExplicitlyConvertibleTo(fromType, toType, DC);
|
bool useAs = TC.isExplicitlyConvertibleTo(fromType, toType, DC);
|
||||||
bool useAsBang = !useAs && TC.checkedCastMaySucceed(fromType, toType,
|
bool useAsBang = !useAs && TC.checkedCastMaySucceed(fromType, toType,
|
||||||
DC);
|
DC);
|
||||||
@@ -6963,7 +6962,7 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case FixKind::AddressOf: {
|
case FixKind::AddressOf: {
|
||||||
auto type = solution.simplifyType(TC, getType(affected))
|
auto type = solution.simplifyType(getType(affected))
|
||||||
->getRValueObjectType();
|
->getRValueObjectType();
|
||||||
TC.diagnose(affected->getLoc(), diag::missing_address_of, type)
|
TC.diagnose(affected->getLoc(), diag::missing_address_of, type)
|
||||||
.fixItInsert(affected->getStartLoc(), "&");
|
.fixItInsert(affected->getStartLoc(), "&");
|
||||||
@@ -6974,9 +6973,9 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
|||||||
if (auto *coerceExpr = dyn_cast<CoerceExpr>(locator->getAnchor())) {
|
if (auto *coerceExpr = dyn_cast<CoerceExpr>(locator->getAnchor())) {
|
||||||
Expr *subExpr = coerceExpr->getSubExpr();
|
Expr *subExpr = coerceExpr->getSubExpr();
|
||||||
auto fromType =
|
auto fromType =
|
||||||
solution.simplifyType(TC, getType(subExpr))->getRValueType();
|
solution.simplifyType(getType(subExpr))->getRValueType();
|
||||||
auto toType =
|
auto toType =
|
||||||
solution.simplifyType(TC, coerceExpr->getCastTypeLoc().getType());
|
solution.simplifyType(coerceExpr->getCastTypeLoc().getType());
|
||||||
auto castKind = TC.typeCheckCheckedCast(
|
auto castKind = TC.typeCheckCheckedCast(
|
||||||
fromType, toType, CheckedCastContextKind::None, DC,
|
fromType, toType, CheckedCastContextKind::None, DC,
|
||||||
coerceExpr->getLoc(), subExpr,
|
coerceExpr->getLoc(), subExpr,
|
||||||
|
|||||||
@@ -1545,23 +1545,17 @@ Type ConstraintSystem::lookThroughImplicitlyUnwrappedOptionalType(Type type) {
|
|||||||
return Type();
|
return Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
Type ConstraintSystem::simplifyType(Type type) {
|
template <typename Fn>
|
||||||
|
Type simplifyTypeImpl(ConstraintSystem &cs, Type type, Fn getFixedTypeFn) {
|
||||||
return type.transform([&](Type type) -> Type {
|
return type.transform([&](Type type) -> Type {
|
||||||
if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer())) {
|
if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer()))
|
||||||
tvt = getRepresentative(tvt);
|
return getFixedTypeFn(tvt);
|
||||||
if (auto fixed = getFixedType(tvt)) {
|
|
||||||
return simplifyType(fixed);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tvt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a dependent member type for which we end up simplifying
|
// If this is a dependent member type for which we end up simplifying
|
||||||
// the base to a non-type-variable, perform lookup.
|
// the base to a non-type-variable, perform lookup.
|
||||||
if (auto depMemTy = dyn_cast<DependentMemberType>(type.getPointer())) {
|
if (auto depMemTy = dyn_cast<DependentMemberType>(type.getPointer())) {
|
||||||
// Simplify the base.
|
// Simplify the base.
|
||||||
Type newBase = simplifyType(depMemTy->getBase());
|
Type newBase = simplifyTypeImpl(cs, depMemTy->getBase(), getFixedTypeFn);
|
||||||
if (!newBase) return type;
|
|
||||||
|
|
||||||
// If nothing changed, we're done.
|
// If nothing changed, we're done.
|
||||||
if (newBase.getPointer() == depMemTy->getBase().getPointer())
|
if (newBase.getPointer() == depMemTy->getBase().getPointer())
|
||||||
@@ -1569,16 +1563,6 @@ Type ConstraintSystem::simplifyType(Type type) {
|
|||||||
|
|
||||||
Type lookupBaseType = newBase->getLValueOrInOutObjectType();
|
Type lookupBaseType = newBase->getLValueOrInOutObjectType();
|
||||||
|
|
||||||
// If the new base is still something we can't handle, just build a
|
|
||||||
// new dependent member type.
|
|
||||||
if (lookupBaseType->is<TypeVariableType>() ||
|
|
||||||
lookupBaseType->is<UnresolvedType>()) {
|
|
||||||
if (auto assocType = depMemTy->getAssocType())
|
|
||||||
return DependentMemberType::get(newBase, assocType);
|
|
||||||
else
|
|
||||||
return DependentMemberType::get(newBase, assocType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dependent member types should only be created for associated types.
|
// Dependent member types should only be created for associated types.
|
||||||
auto assocType = depMemTy->getAssocType();
|
auto assocType = depMemTy->getAssocType();
|
||||||
assert(depMemTy->getAssocType());
|
assert(depMemTy->getAssocType());
|
||||||
@@ -1586,7 +1570,7 @@ Type ConstraintSystem::simplifyType(Type type) {
|
|||||||
if (!lookupBaseType->mayHaveMembers()) return type;
|
if (!lookupBaseType->mayHaveMembers()) return type;
|
||||||
|
|
||||||
auto result = assocType->getDeclaredInterfaceType()
|
auto result = assocType->getDeclaredInterfaceType()
|
||||||
.subst(DC->getParentModule(),
|
.subst(cs.DC->getParentModule(),
|
||||||
lookupBaseType->getContextSubstitutions(
|
lookupBaseType->getContextSubstitutions(
|
||||||
assocType->getDeclContext()));
|
assocType->getDeclContext()));
|
||||||
|
|
||||||
@@ -1599,78 +1583,45 @@ Type ConstraintSystem::simplifyType(Type type) {
|
|||||||
// If this is a FunctionType and we inferred new function attributes, apply
|
// If this is a FunctionType and we inferred new function attributes, apply
|
||||||
// them.
|
// them.
|
||||||
if (auto ft = dyn_cast<FunctionType>(type.getPointer())) {
|
if (auto ft = dyn_cast<FunctionType>(type.getPointer())) {
|
||||||
auto it = extraFunctionAttrs.find(ft);
|
auto it = cs.extraFunctionAttrs.find(ft);
|
||||||
if (it != extraFunctionAttrs.end()) {
|
if (it != cs.extraFunctionAttrs.end()) {
|
||||||
auto extInfo = ft->getExtInfo();
|
auto extInfo = ft->getExtInfo();
|
||||||
if (it->second.isNoEscape())
|
if (it->second.isNoEscape())
|
||||||
extInfo = extInfo.withNoEscape();
|
extInfo = extInfo.withNoEscape();
|
||||||
if (it->second.throws())
|
if (it->second.throws())
|
||||||
extInfo = extInfo.withThrows();
|
extInfo = extInfo.withThrows();
|
||||||
return FunctionType::get(ft->getInput(), ft->getResult(), extInfo);
|
return FunctionType::get(
|
||||||
|
simplifyTypeImpl(cs, ft->getInput(), getFixedTypeFn),
|
||||||
|
simplifyTypeImpl(cs, ft->getResult(), getFixedTypeFn),
|
||||||
|
extInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Type Solution::simplifyType(TypeChecker &tc, Type type) const {
|
Type ConstraintSystem::simplifyType(Type type) {
|
||||||
// FIXME: Nearly identical to ConstraintSystem::simplifyType().
|
// Map type variables down to the fixed types of their representatives.
|
||||||
return type.transform([&](Type type) -> Type {
|
return simplifyTypeImpl(
|
||||||
if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer())) {
|
*this, type,
|
||||||
auto known = typeBindings.find(tvt);
|
[&](TypeVariableType *tvt) -> Type {
|
||||||
assert(known != typeBindings.end());
|
tvt = getRepresentative(tvt);
|
||||||
return known->second;
|
if (auto fixed = getFixedType(tvt)) {
|
||||||
}
|
return simplifyType(fixed);
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a dependent member type for which we end up simplifying
|
return tvt;
|
||||||
// the base to a non-type-variable, perform lookup.
|
});
|
||||||
if (auto depMemTy = dyn_cast<DependentMemberType>(type.getPointer())) {
|
}
|
||||||
// Simplify the base.
|
|
||||||
Type newBase = simplifyType(tc, depMemTy->getBase());
|
Type Solution::simplifyType(Type type) const {
|
||||||
if (!newBase) return type;
|
// Map type variables to fixed types from bindings.
|
||||||
|
return simplifyTypeImpl(
|
||||||
// If nothing changed, we're done.
|
getConstraintSystem(), type,
|
||||||
if (newBase.getPointer() == depMemTy->getBase().getPointer())
|
[&](TypeVariableType *tvt) -> Type {
|
||||||
return type;
|
auto known = typeBindings.find(tvt);
|
||||||
|
assert(known != typeBindings.end());
|
||||||
Type lookupBaseType = newBase;
|
return known->second;
|
||||||
|
});
|
||||||
// Look through an inout type.
|
|
||||||
if (auto inout = lookupBaseType->getAs<InOutType>())
|
|
||||||
lookupBaseType = inout->getObjectType();
|
|
||||||
|
|
||||||
// Look through a metatype.
|
|
||||||
if (auto metatype = lookupBaseType->getAs<AnyMetatypeType>())
|
|
||||||
lookupBaseType = metatype->getInstanceType();
|
|
||||||
|
|
||||||
// Dependent member types should only be created for associated types.
|
|
||||||
auto assocType = depMemTy->getAssocType();
|
|
||||||
assert(depMemTy->getAssocType());
|
|
||||||
|
|
||||||
return lookupBaseType->getTypeOfMember(
|
|
||||||
getConstraintSystem().DC->getParentModule(), assocType, &tc,
|
|
||||||
assocType->getDeclaredInterfaceType());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a FunctionType and we inferred new function attributes, apply
|
|
||||||
// them.
|
|
||||||
if (auto ft = dyn_cast<FunctionType>(type.getPointer())) {
|
|
||||||
auto &CS = getConstraintSystem();
|
|
||||||
auto it = CS.extraFunctionAttrs.find(ft);
|
|
||||||
if (it != CS.extraFunctionAttrs.end()) {
|
|
||||||
auto extInfo = ft->getExtInfo();
|
|
||||||
if (it->second.isNoEscape())
|
|
||||||
extInfo = extInfo.withNoEscape();
|
|
||||||
if (it->second.throws())
|
|
||||||
extInfo = extInfo.withThrows();
|
|
||||||
return FunctionType::get(simplifyType(tc, ft->getInput()),
|
|
||||||
simplifyType(tc, ft->getResult()),
|
|
||||||
extInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -552,7 +552,7 @@ public:
|
|||||||
|
|
||||||
/// \brief Simplify the given type by substituting all occurrences of
|
/// \brief Simplify the given type by substituting all occurrences of
|
||||||
/// type variables for their fixed types.
|
/// type variables for their fixed types.
|
||||||
Type simplifyType(TypeChecker &tc, Type type) const;
|
Type simplifyType(Type type) const;
|
||||||
|
|
||||||
/// \brief Coerce the given expression to the given type.
|
/// \brief Coerce the given expression to the given type.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1676,7 +1676,7 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
|
|||||||
|
|
||||||
// Get the expression's simplified type.
|
// Get the expression's simplified type.
|
||||||
auto &solution = viable[0];
|
auto &solution = viable[0];
|
||||||
Type exprType = solution.simplifyType(*this, expr->getType());
|
Type exprType = solution.simplifyType(expr->getType());
|
||||||
|
|
||||||
assert(exprType && !exprType->hasTypeVariable() &&
|
assert(exprType && !exprType->hasTypeVariable() &&
|
||||||
"free type variable with FreeTypeVariableBinding::GenericParameters?");
|
"free type variable with FreeTypeVariableBinding::GenericParameters?");
|
||||||
@@ -1791,8 +1791,8 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
|
|||||||
solution.dump(log);
|
solution.dump(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr->setType(solution.simplifyType(*this, expr->getType()));
|
expr->setType(solution.simplifyType(expr->getType()));
|
||||||
CCE->setType(solution.simplifyType(*this, CCE->getType()));
|
CCE->setType(solution.simplifyType(CCE->getType()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1892,7 +1892,7 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
|
|||||||
// Figure out what type the constraints decided on.
|
// Figure out what type the constraints decided on.
|
||||||
auto &cs = solution.getConstraintSystem();
|
auto &cs = solution.getConstraintSystem();
|
||||||
auto &tc = cs.getTypeChecker();
|
auto &tc = cs.getTypeChecker();
|
||||||
InitType = solution.simplifyType(tc, InitType);
|
InitType = solution.simplifyType(InitType);
|
||||||
|
|
||||||
// Convert the initializer to the type of the pattern.
|
// Convert the initializer to the type of the pattern.
|
||||||
// ignoreTopLevelInjection = Binding->isConditional()
|
// ignoreTopLevelInjection = Binding->isConditional()
|
||||||
@@ -2137,8 +2137,8 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
|
|||||||
// Figure out what types the constraints decided on.
|
// Figure out what types the constraints decided on.
|
||||||
auto &cs = solution.getConstraintSystem();
|
auto &cs = solution.getConstraintSystem();
|
||||||
auto &tc = cs.getTypeChecker();
|
auto &tc = cs.getTypeChecker();
|
||||||
InitType = solution.simplifyType(tc, InitType);
|
InitType = solution.simplifyType(InitType);
|
||||||
SequenceType = solution.simplifyType(tc, SequenceType);
|
SequenceType = solution.simplifyType(SequenceType);
|
||||||
|
|
||||||
// Perform any necessary conversions of the sequence (e.g. [T]! -> [T]).
|
// Perform any necessary conversions of the sequence (e.g. [T]! -> [T]).
|
||||||
if (tc.convertToType(expr, SequenceType, cs.DC)) {
|
if (tc.convertToType(expr, SequenceType, cs.DC)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user