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();
|
||||
|
||||
// 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.
|
||||
auto openedTypes = OpenedTypes.find(locator);
|
||||
@@ -816,7 +816,7 @@ namespace {
|
||||
Type containerTy =
|
||||
openedFullType->castTo<FunctionType>()
|
||||
->getInput()->getRValueInstanceType();
|
||||
containerTy = solution.simplifyType(tc, containerTy);
|
||||
containerTy = solution.simplifyType(containerTy);
|
||||
|
||||
// If we opened up an existential when referencing this member, update
|
||||
// the base accordingly.
|
||||
@@ -1116,7 +1116,7 @@ namespace {
|
||||
/// \brief Simplify the given type by substituting all occurrences of
|
||||
/// type variables for their fixed types.
|
||||
Type simplifyType(Type type) {
|
||||
return solution.simplifyType(cs.getTypeChecker(), type);
|
||||
return solution.simplifyType(type);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -1316,7 +1316,7 @@ namespace {
|
||||
// Convert the base.
|
||||
auto openedFullFnType = selected->openedFullType->castTo<FunctionType>();
|
||||
auto openedBaseType = openedFullFnType->getInput();
|
||||
containerTy = solution.simplifyType(tc, openedBaseType);
|
||||
containerTy = solution.simplifyType(openedBaseType);
|
||||
base = coerceObjectArgumentToType(
|
||||
base, containerTy, subscript, AccessSemantics::Ordinary,
|
||||
locator.withPathElement(ConstraintLocator::MemberRefBase));
|
||||
@@ -6890,7 +6890,7 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
||||
|
||||
case FixKind::ForceOptional: {
|
||||
const Expr *unwrapped = affected->getValueProvidingExpr();
|
||||
auto type = solution.simplifyType(TC, getType(affected))
|
||||
auto type = solution.simplifyType(getType(affected))
|
||||
->getRValueObjectType();
|
||||
|
||||
if (auto tryExpr = dyn_cast<OptionalTryExpr>(unwrapped)) {
|
||||
@@ -6916,7 +6916,7 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
||||
}
|
||||
|
||||
case FixKind::OptionalChaining: {
|
||||
auto type = solution.simplifyType(TC, getType(affected))
|
||||
auto type = solution.simplifyType(getType(affected))
|
||||
->getRValueObjectType();
|
||||
auto diag = TC.diagnose(affected->getLoc(),
|
||||
diag::missing_unwrap_optional, type);
|
||||
@@ -6925,10 +6925,9 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
||||
}
|
||||
|
||||
case FixKind::ForceDowncast: {
|
||||
auto fromType = solution.simplifyType(TC, getType(affected))
|
||||
auto fromType = solution.simplifyType(getType(affected))
|
||||
->getRValueObjectType();
|
||||
Type toType = solution.simplifyType(TC,
|
||||
fix.first.getTypeArgument(*this));
|
||||
Type toType = solution.simplifyType(fix.first.getTypeArgument(*this));
|
||||
bool useAs = TC.isExplicitlyConvertibleTo(fromType, toType, DC);
|
||||
bool useAsBang = !useAs && TC.checkedCastMaySucceed(fromType, toType,
|
||||
DC);
|
||||
@@ -6963,7 +6962,7 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
||||
}
|
||||
|
||||
case FixKind::AddressOf: {
|
||||
auto type = solution.simplifyType(TC, getType(affected))
|
||||
auto type = solution.simplifyType(getType(affected))
|
||||
->getRValueObjectType();
|
||||
TC.diagnose(affected->getLoc(), diag::missing_address_of, type)
|
||||
.fixItInsert(affected->getStartLoc(), "&");
|
||||
@@ -6974,9 +6973,9 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
|
||||
if (auto *coerceExpr = dyn_cast<CoerceExpr>(locator->getAnchor())) {
|
||||
Expr *subExpr = coerceExpr->getSubExpr();
|
||||
auto fromType =
|
||||
solution.simplifyType(TC, getType(subExpr))->getRValueType();
|
||||
solution.simplifyType(getType(subExpr))->getRValueType();
|
||||
auto toType =
|
||||
solution.simplifyType(TC, coerceExpr->getCastTypeLoc().getType());
|
||||
solution.simplifyType(coerceExpr->getCastTypeLoc().getType());
|
||||
auto castKind = TC.typeCheckCheckedCast(
|
||||
fromType, toType, CheckedCastContextKind::None, DC,
|
||||
coerceExpr->getLoc(), subExpr,
|
||||
|
||||
@@ -1545,23 +1545,17 @@ Type ConstraintSystem::lookThroughImplicitlyUnwrappedOptionalType(Type 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 {
|
||||
if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer())) {
|
||||
tvt = getRepresentative(tvt);
|
||||
if (auto fixed = getFixedType(tvt)) {
|
||||
return simplifyType(fixed);
|
||||
}
|
||||
|
||||
return tvt;
|
||||
}
|
||||
if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer()))
|
||||
return getFixedTypeFn(tvt);
|
||||
|
||||
// If this is a dependent member type for which we end up simplifying
|
||||
// the base to a non-type-variable, perform lookup.
|
||||
if (auto depMemTy = dyn_cast<DependentMemberType>(type.getPointer())) {
|
||||
// Simplify the base.
|
||||
Type newBase = simplifyType(depMemTy->getBase());
|
||||
if (!newBase) return type;
|
||||
Type newBase = simplifyTypeImpl(cs, depMemTy->getBase(), getFixedTypeFn);
|
||||
|
||||
// If nothing changed, we're done.
|
||||
if (newBase.getPointer() == depMemTy->getBase().getPointer())
|
||||
@@ -1569,16 +1563,6 @@ Type ConstraintSystem::simplifyType(Type type) {
|
||||
|
||||
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.
|
||||
auto assocType = depMemTy->getAssocType();
|
||||
assert(depMemTy->getAssocType());
|
||||
@@ -1586,7 +1570,7 @@ Type ConstraintSystem::simplifyType(Type type) {
|
||||
if (!lookupBaseType->mayHaveMembers()) return type;
|
||||
|
||||
auto result = assocType->getDeclaredInterfaceType()
|
||||
.subst(DC->getParentModule(),
|
||||
.subst(cs.DC->getParentModule(),
|
||||
lookupBaseType->getContextSubstitutions(
|
||||
assocType->getDeclContext()));
|
||||
|
||||
@@ -1599,74 +1583,16 @@ Type ConstraintSystem::simplifyType(Type type) {
|
||||
// If this is a FunctionType and we inferred new function attributes, apply
|
||||
// them.
|
||||
if (auto ft = dyn_cast<FunctionType>(type.getPointer())) {
|
||||
auto it = extraFunctionAttrs.find(ft);
|
||||
if (it != extraFunctionAttrs.end()) {
|
||||
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(ft->getInput(), ft->getResult(), extInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return type;
|
||||
});
|
||||
}
|
||||
|
||||
Type Solution::simplifyType(TypeChecker &tc, Type type) const {
|
||||
// FIXME: Nearly identical to ConstraintSystem::simplifyType().
|
||||
return type.transform([&](Type type) -> Type {
|
||||
if (auto tvt = dyn_cast<TypeVariableType>(type.getPointer())) {
|
||||
auto known = typeBindings.find(tvt);
|
||||
assert(known != typeBindings.end());
|
||||
return known->second;
|
||||
}
|
||||
|
||||
// If this is a dependent member type for which we end up simplifying
|
||||
// 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());
|
||||
if (!newBase) return type;
|
||||
|
||||
// If nothing changed, we're done.
|
||||
if (newBase.getPointer() == depMemTy->getBase().getPointer())
|
||||
return type;
|
||||
|
||||
Type lookupBaseType = newBase;
|
||||
|
||||
// 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()),
|
||||
return FunctionType::get(
|
||||
simplifyTypeImpl(cs, ft->getInput(), getFixedTypeFn),
|
||||
simplifyTypeImpl(cs, ft->getResult(), getFixedTypeFn),
|
||||
extInfo);
|
||||
}
|
||||
}
|
||||
@@ -1674,3 +1600,28 @@ Type Solution::simplifyType(TypeChecker &tc, Type type) const {
|
||||
return type;
|
||||
});
|
||||
}
|
||||
|
||||
Type ConstraintSystem::simplifyType(Type type) {
|
||||
// Map type variables down to the fixed types of their representatives.
|
||||
return simplifyTypeImpl(
|
||||
*this, type,
|
||||
[&](TypeVariableType *tvt) -> Type {
|
||||
tvt = getRepresentative(tvt);
|
||||
if (auto fixed = getFixedType(tvt)) {
|
||||
return simplifyType(fixed);
|
||||
}
|
||||
|
||||
return tvt;
|
||||
});
|
||||
}
|
||||
|
||||
Type Solution::simplifyType(Type type) const {
|
||||
// Map type variables to fixed types from bindings.
|
||||
return simplifyTypeImpl(
|
||||
getConstraintSystem(), type,
|
||||
[&](TypeVariableType *tvt) -> Type {
|
||||
auto known = typeBindings.find(tvt);
|
||||
assert(known != typeBindings.end());
|
||||
return known->second;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ public:
|
||||
|
||||
/// \brief Simplify the given type by substituting all occurrences of
|
||||
/// 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.
|
||||
///
|
||||
|
||||
@@ -1676,7 +1676,7 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
|
||||
|
||||
// Get the expression's simplified type.
|
||||
auto &solution = viable[0];
|
||||
Type exprType = solution.simplifyType(*this, expr->getType());
|
||||
Type exprType = solution.simplifyType(expr->getType());
|
||||
|
||||
assert(exprType && !exprType->hasTypeVariable() &&
|
||||
"free type variable with FreeTypeVariableBinding::GenericParameters?");
|
||||
@@ -1791,8 +1791,8 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
|
||||
solution.dump(log);
|
||||
}
|
||||
|
||||
expr->setType(solution.simplifyType(*this, expr->getType()));
|
||||
CCE->setType(solution.simplifyType(*this, CCE->getType()));
|
||||
expr->setType(solution.simplifyType(expr->getType()));
|
||||
CCE->setType(solution.simplifyType(CCE->getType()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1892,7 +1892,7 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
|
||||
// Figure out what type the constraints decided on.
|
||||
auto &cs = solution.getConstraintSystem();
|
||||
auto &tc = cs.getTypeChecker();
|
||||
InitType = solution.simplifyType(tc, InitType);
|
||||
InitType = solution.simplifyType(InitType);
|
||||
|
||||
// Convert the initializer to the type of the pattern.
|
||||
// ignoreTopLevelInjection = Binding->isConditional()
|
||||
@@ -2137,8 +2137,8 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
|
||||
// Figure out what types the constraints decided on.
|
||||
auto &cs = solution.getConstraintSystem();
|
||||
auto &tc = cs.getTypeChecker();
|
||||
InitType = solution.simplifyType(tc, InitType);
|
||||
SequenceType = solution.simplifyType(tc, SequenceType);
|
||||
InitType = solution.simplifyType(InitType);
|
||||
SequenceType = solution.simplifyType(SequenceType);
|
||||
|
||||
// Perform any necessary conversions of the sequence (e.g. [T]! -> [T]).
|
||||
if (tc.convertToType(expr, SequenceType, cs.DC)) {
|
||||
|
||||
Reference in New Issue
Block a user