Replace Expr::getType() with ConstraintSystem::getType().

Update CSGen/CSApply/CSSolver to primarily use getType() from
ConstraintSystem.

Currently getType() just returns the type on the expression. As with
setType(), which continues to set the type on the expression, this
will be updated once all the other changes are in place.

This change also moves coerceToRValue from TypeChecker to
CosntraintSystem so that it can access the expression type map in the
constraint system.
This commit is contained in:
Mark Lacey
2016-12-11 16:44:35 -07:00
parent 294f90a68b
commit 0a8678cf19
6 changed files with 305 additions and 274 deletions

View File

@@ -175,7 +175,7 @@ namespace {
if (isa<IntegerLiteralExpr>(expr)) {
LTI.haveIntLiteral = true;
auto tyvar = expr->getType()->getAs<TypeVariableType>();
auto tyvar = CS.getType(expr)->getAs<TypeVariableType>();
if (tyvar) {
LTI.intLiteralTyvars.push_back(tyvar);
@@ -186,7 +186,7 @@ namespace {
if (isa<FloatLiteralExpr>(expr)) {
LTI.haveFloatLiteral = true;
auto tyvar = expr->getType()->getAs<TypeVariableType>();
auto tyvar = CS.getType(expr)->getAs<TypeVariableType>();
if (tyvar) {
LTI.floatLiteralTyvars.push_back(tyvar);
@@ -197,7 +197,8 @@ namespace {
if (isa<StringLiteralExpr>(expr)) {
LTI.haveStringLiteral = true;
auto tyvar = expr->getType()->getAs<TypeVariableType>();
auto tyvar = CS.getType(expr)->getAs<TypeVariableType>();
if (tyvar) {
LTI.stringLiteralTyvars.push_back(tyvar);
@@ -208,8 +209,8 @@ namespace {
if (auto UDE = dyn_cast<UnresolvedDotExpr>(expr)) {
if (UDE->getType())
LTI.collectedTypes.insert(UDE->getType().getPointer());
if (CS.hasType(UDE))
LTI.collectedTypes.insert(CS.getType(UDE).getPointer());
// Don't recurse into the base expression.
return { false, expr };
@@ -230,8 +231,8 @@ namespace {
if (auto varDecl = dyn_cast<VarDecl>(DRE->getDecl())) {
if (varDecl->isAnonClosureParam()) {
LTI.anonClosureParams.push_back(DRE);
} else if (DRE->getType()) {
LTI.collectedTypes.insert(DRE->getType().getPointer());
} else if (CS.hasType(DRE)) {
LTI.collectedTypes.insert(CS.getType(DRE).getPointer());
}
return { false, expr };
}
@@ -280,7 +281,7 @@ namespace {
// Coercion exprs have a rigid type, so there's no use in gathering info
// about them.
if (isa<CoerceExpr>(expr)) {
LTI.collectedTypes.insert(expr->getType().getPointer());
LTI.collectedTypes.insert(CS.getType(expr).getPointer());
return { false, expr };
}
@@ -334,8 +335,8 @@ namespace {
if (acp1->getDecl()->getName().str() ==
acp2->getDecl()->getName().str()) {
auto tyvar1 = acp1->getType()->getAs<TypeVariableType>();
auto tyvar2 = acp2->getType()->getAs<TypeVariableType>();
auto tyvar1 = CS.getType(acp1)->getAs<TypeVariableType>();
auto tyvar2 = CS.getType(acp2)->getAs<TypeVariableType>();
mergeRepresentativeEquivalenceClasses(CS, tyvar1, tyvar2);
}
@@ -395,8 +396,8 @@ namespace {
if (binExp1 == binExp2)
continue;
auto fnTy1 = binExp1->getType()->getAs<TypeVariableType>();
auto fnTy2 = binExp2->getType()->getAs<TypeVariableType>();
auto fnTy1 = CS.getType(binExp1)->getAs<TypeVariableType>();
auto fnTy2 = CS.getType(binExp2)->getAs<TypeVariableType>();
if (!(fnTy1 && fnTy2))
return;
@@ -433,10 +434,10 @@ namespace {
rep1,
favoredTy,
CS.getConstraintLocator(binExp1));
}
}
auto odTy1 = ODR1->getType()->getAs<TypeVariableType>();
auto odTy2 = ODR2->getType()->getAs<TypeVariableType>();
auto odTy1 = CS.getType(ODR1)->getAs<TypeVariableType>();
auto odTy2 = CS.getType(ODR2)->getAs<TypeVariableType>();
if (odTy1 && odTy2) {
auto odRep1 = CS.getRepresentative(odTy1);
@@ -556,7 +557,7 @@ namespace {
std::function<bool(ValueDecl *)>
mustConsider = nullptr) {
// Find the type variable associated with the function, if any.
auto tyvarType = expr->getFn()->getType()->getAs<TypeVariableType>();
auto tyvarType = CS.getType(expr->getFn())->getAs<TypeVariableType>();
if (!tyvarType)
return;
@@ -758,10 +759,11 @@ namespace {
auto resultTy = ArchetypeBuilder::mapTypeIntoContext(
value->getInnermostDeclContext(), fnTy->getResult());
auto contextualTy = CS.getContextualType(expr);
return isFavoredParamAndArg(CS, paramTy, expr->getArg(),
expr->getArg()->getType()->getWithoutParens()) &&
(!contextualTy || contextualTy->isEqual(resultTy));
return isFavoredParamAndArg(
CS, paramTy, expr->getArg(),
CS.getType(expr->getArg())->getWithoutParens()) &&
(!contextualTy || contextualTy->isEqual(resultTy));
};
favorCallOverloads(expr, CS, isFavoredDecl);
@@ -770,7 +772,7 @@ namespace {
void favorMatchingOverloadExprs(ApplyExpr *expr,
ConstraintSystem &CS) {
// Find the argument type.
size_t nArgs = getOperandCount(expr->getArg()->getType());
size_t nArgs = getOperandCount(CS.getType(expr->getArg()));
auto fnExpr = expr->getFn();
// Check to ensure that we have an OverloadedDeclRef, and that we're not
@@ -866,9 +868,10 @@ namespace {
// to any contextual type associated with the application expression.
// Find the argument types.
auto argTy = expr->getArg()->getType();
auto argTy = CS.getType(expr->getArg());
auto argTupleTy = argTy->castTo<TupleType>();
auto argTupleExpr = dyn_cast<TupleExpr>(expr->getArg());
Type firstArgTy = argTupleTy->getElement(0).getType()->getWithoutParens();
Type secondArgTy = argTupleTy->getElement(1).getType()->getWithoutParens();
@@ -1001,7 +1004,7 @@ namespace {
// The base must have a member of the given name, such that accessing
// that member through the base returns a value convertible to the type
// of this expression.
auto baseTy = base->getType();
auto baseTy = CS.getType(base);
auto tv = CS.createTypeVariable(
CS.getConstraintLocator(expr, ConstraintLocator::Member),
TVO_CanBindToLValue);
@@ -1025,9 +1028,9 @@ namespace {
auto memberLocator =
CS.getConstraintLocator(expr, ConstraintLocator::Member);
auto tv = CS.createTypeVariable(memberLocator, TVO_CanBindToLValue);
OverloadChoice choice(base->getType(), decl, /*isSpecialized=*/false,
functionRefKind);
OverloadChoice choice(CS.getType(base), decl, /*isSpecialized=*/false,
functionRefKind);
auto locator = CS.getConstraintLocator(expr, ConstraintLocator::Member);
CS.addBindOverloadConstraint(tv, choice, locator);
return tv;
@@ -1057,8 +1060,8 @@ namespace {
if (auto subscriptExpr = dyn_cast<SubscriptExpr>(expr)) {
auto isLValueBase = false;
auto baseTy = subscriptExpr->getBase()->getType();
Type baseTy = CS.getType(subscriptExpr->getBase());
if (baseTy->getAs<LValueType>()) {
isLValueBase = true;
baseTy = baseTy->getLValueOrInOutObjectType();
@@ -1087,8 +1090,8 @@ namespace {
} else if (auto dictTy = CS.isDictionaryType(baseTy)) {
auto keyTy = dictTy->first;
auto valueTy = dictTy->second;
if (isFavoredParamAndArg(CS, keyTy, index, index->getType())) {
if (isFavoredParamAndArg(CS, keyTy, index, CS.getType(index))) {
outputTy = OptionalType::get(valueTy);
if (isLValueBase)
@@ -1118,7 +1121,7 @@ namespace {
// Add the member constraint for a subscript declaration.
// FIXME: lame name!
auto baseTy = base->getType();
auto baseTy = CS.getType(base);
auto fnTy = FunctionType::get(inputTv, outputTy);
// FIXME: synthesizeMaterializeForSet() wants to statically dispatch to
@@ -1137,7 +1140,7 @@ namespace {
// Add the constraint that the index expression's type be convertible
// to the input type of the subscript operator.
CS.addConstraint(ConstraintKind::ArgumentTupleConversion,
index->getType(), inputTv, indexLocator);
CS.getType(index), inputTv, indexLocator);
return outputTy;
}
@@ -1208,7 +1211,7 @@ namespace {
auto returnTyV = CS.createTypeVariable(locator, /*options=*/0);
auto methodTy = FunctionType::get(segmentTyV, returnTyV);
CS.addConstraint(ConstraintKind::Conversion, segment->getType(),
CS.addConstraint(ConstraintKind::Conversion, CS.getType(segment),
segmentTyV, locator);
DeclName segmentName(C, C.Id_init, { C.Id_stringInterpolationSegment });
@@ -1277,9 +1280,10 @@ namespace {
}
auto *constr = cast<ConstructorDecl>(constrs.front());
auto constrParamType = tc.getObjectLiteralParameterType(expr, constr);
CS.addConstraint(ConstraintKind::ArgumentTupleConversion,
expr->getArg()->getType(), constrParamType,
CS.getConstraintLocator(expr, ConstraintLocator::ApplyArgument));
CS.addConstraint(
ConstraintKind::ArgumentTupleConversion, CS.getType(expr->getArg()),
constrParamType,
CS.getConstraintLocator(expr, ConstraintLocator::ApplyArgument));
Type result = tv;
if (constr->getFailability() != OTK_None) {
@@ -1455,7 +1459,7 @@ namespace {
CS.getConstraintLocator(expr, ConstraintLocator::RvalueAdjustment));
// The function/enum case must be callable with the given argument.
auto funcTy = FunctionType::get(arg->getType(), outputTy);
auto funcTy = FunctionType::get(CS.getType(arg), outputTy);
CS.addConstraint(ConstraintKind::ApplicableFunction, funcTy,
memberTy,
CS.getConstraintLocator(expr, ConstraintLocator::ApplyFunction));
@@ -1481,7 +1485,7 @@ namespace {
// Open a member constraint for constructor delegations on the
// subexpr type.
if (CS.TC.getSelfForInitDelegationInConstructor(CS.DC, expr)) {
auto baseTy = expr->getBase()->getType()
auto baseTy = CS.getType(expr->getBase())
->getLValueOrInOutObjectType();
// 'self' or 'super' will reference an instance, but the constructor
@@ -1513,7 +1517,7 @@ namespace {
}
Type visitUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *expr) {
auto baseTy = expr->getSubExpr()->getType();
auto baseTy = CS.getType(expr->getSubExpr());
// We currently only support explicit specialization of generic types.
// FIXME: We could support explicit function specialization.
@@ -1587,11 +1591,11 @@ namespace {
}
Type visitIdentityExpr(IdentityExpr *expr) {
return expr->getSubExpr()->getType();
return CS.getType(expr->getSubExpr());
}
Type visitAnyTryExpr(AnyTryExpr *expr) {
return expr->getSubExpr()->getType();
return CS.getType(expr->getSubExpr());
}
Type visitOptionalTryExpr(OptionalTryExpr *expr) {
@@ -1603,7 +1607,7 @@ namespace {
return Type();
CS.addConstraint(ConstraintKind::OptionalObject,
optTy, expr->getSubExpr()->getType(),
optTy, CS.getType(expr->getSubExpr()),
CS.getConstraintLocator(expr));
return optTy;
}
@@ -1614,7 +1618,7 @@ namespace {
}
auto &ctx = CS.getASTContext();
return ParenType::get(ctx, expr->getSubExpr()->getType());
return ParenType::get(ctx, CS.getType(expr->getSubExpr()));
}
Type visitTupleExpr(TupleExpr *expr) {
@@ -1623,7 +1627,7 @@ namespace {
SmallVector<TupleTypeElt, 4> elements;
elements.reserve(expr->getNumElements());
for (unsigned i = 0, n = expr->getNumElements(); i != n; ++i) {
elements.push_back(TupleTypeElt(expr->getElement(i)->getType(),
elements.push_back(TupleTypeElt(CS.getType(expr->getElement(i)),
expr->getElementName(i)));
}
@@ -2264,7 +2268,7 @@ namespace {
auto bound = LValueType::get(lvalue);
auto result = InOutType::get(lvalue);
CS.addConstraint(ConstraintKind::Conversion,
expr->getSubExpr()->getType(), bound,
CS.getType(expr->getSubExpr()), bound,
CS.getConstraintLocator(expr->getSubExpr()));
return result;
}
@@ -2273,7 +2277,7 @@ namespace {
auto tv = CS.createTypeVariable(CS.getConstraintLocator(expr),
/*options=*/0);
CS.addConstraint(ConstraintKind::DynamicTypeOf, tv,
expr->getBase()->getType(),
CS.getType(expr->getBase()),
CS.getConstraintLocator(expr, ConstraintLocator::RvalueAdjustment));
return tv;
}
@@ -2288,7 +2292,7 @@ namespace {
auto fnExpr = expr->getFn();
if (isa<DeclRefExpr>(fnExpr)) {
if (auto fnType = fnExpr->getType()->getAs<AnyFunctionType>()) {
if (auto fnType = CS.getType(fnExpr)->getAs<AnyFunctionType>()) {
outputTy = fnType->getResult();
}
} else if (auto TE = dyn_cast<TypeExpr>(fnExpr)) {
@@ -2394,11 +2398,11 @@ namespace {
if (isa<ClosureExpr>(fnExpr->getSemanticsProvidingExpr()))
extInfo = extInfo.withNoEscape();
auto funcTy = FunctionType::get(expr->getArg()->getType(), outputTy,
auto funcTy = FunctionType::get(CS.getType(expr->getArg()), outputTy,
extInfo);
CS.addConstraint(ConstraintKind::ApplicableFunction, funcTy,
expr->getFn()->getType(),
CS.getType(expr->getFn()),
CS.getConstraintLocator(expr, ConstraintLocator::ApplyFunction));
return outputTy;
@@ -2448,7 +2452,7 @@ namespace {
// Condition must convert to Bool.
CS.addConstraint(ConstraintKind::Conversion,
expr->getCondExpr()->getType(),
CS.getType(expr->getCondExpr()),
boolDecl->getDeclaredType(),
CS.getConstraintLocator(expr->getCondExpr()));
@@ -2456,10 +2460,10 @@ namespace {
auto resultTy = CS.createTypeVariable(CS.getConstraintLocator(expr),
TVO_PrefersSubtypeBinding);
CS.addConstraint(ConstraintKind::Conversion,
expr->getThenExpr()->getType(), resultTy,
CS.getType(expr->getThenExpr()), resultTy,
CS.getConstraintLocator(expr->getThenExpr()));
CS.addConstraint(ConstraintKind::Conversion,
expr->getElseExpr()->getType(), resultTy,
CS.getType(expr->getElseExpr()), resultTy,
CS.getConstraintLocator(expr->getElseExpr()));
return resultTy;
}
@@ -2485,7 +2489,7 @@ namespace {
CS.getConstraintLocator(expr));
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
auto fromType = fromExpr->getType();
auto fromType = CS.getType(fromExpr);
auto locator = CS.getConstraintLocator(fromExpr);
// The source type can be checked-cast to the destination type.
@@ -2508,7 +2512,7 @@ namespace {
CS.getConstraintLocator(expr));
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
auto fromType = expr->getSubExpr()->getType();
auto fromType = CS.getType(expr->getSubExpr());
auto locator = CS.getConstraintLocator(expr);
if (CS.shouldAttemptFixes()) {
@@ -2550,7 +2554,7 @@ namespace {
CS.getConstraintLocator(expr));
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
auto fromType = fromExpr->getType();
auto fromType = CS.getType(fromExpr);
auto locator = CS.getConstraintLocator(fromExpr);
CS.addConstraint(ConstraintKind::CheckedCast, fromType, toType, locator);
return OptionalType::get(toType);
@@ -2571,7 +2575,7 @@ namespace {
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
// Add a checked cast constraint.
auto fromType = expr->getSubExpr()->getType();
auto fromType = CS.getType(expr->getSubExpr());
CS.addConstraint(ConstraintKind::CheckedCast, fromType, toType,
CS.getConstraintLocator(expr));
@@ -2599,7 +2603,7 @@ namespace {
// The source must be convertible to the destination.
CS.addConstraint(ConstraintKind::Conversion,
expr->getSrc()->getType(), destTy,
CS.getType(expr->getSrc()), destTy,
CS.getConstraintLocator(expr->getSrc()));
return TupleType::getEmpty(CS.getASTContext());
@@ -2634,7 +2638,7 @@ namespace {
// The result is the object type of the optional subexpression.
CS.addConstraint(ConstraintKind::OptionalObject,
expr->getSubExpr()->getType(), objectTy,
CS.getType(expr->getSubExpr()), objectTy,
locator);
return objectTy;
}
@@ -2652,7 +2656,7 @@ namespace {
return Type();
CS.addConstraint(ConstraintKind::Conversion,
expr->getSubExpr()->getType(), optTy,
CS.getType(expr->getSubExpr()), optTy,
CS.getConstraintLocator(expr));
return optTy;
}
@@ -2667,7 +2671,7 @@ namespace {
// The result is the object type of the optional subexpression.
CS.addConstraint(ConstraintKind::OptionalObject,
expr->getSubExpr()->getType(), objectTy,
CS.getType(expr->getSubExpr()), objectTy,
locator);
return objectTy;
}
@@ -2694,7 +2698,7 @@ namespace {
}
// NOTE: The type loc may be there but have failed to validate, in which
// case we return the null type.
return E->getType();
return CS.getType(E);
}
Type visitObjCSelectorExpr(ObjCSelectorExpr *E) {
@@ -2831,7 +2835,7 @@ namespace {
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
if (closure->hasSingleExpressionBody()) {
auto &CS = CG.getConstraintSystem();
Type closureTy = closure->getType();
Type closureTy = CS.getType(closure);
// If the function type has an error in it, we don't want to solve the
// system.
@@ -2845,7 +2849,7 @@ namespace {
// Visit the body. It's type needs to be convertible to the function's
// return type.
auto resultTy = closureTy->castTo<FunctionType>()->getResult();
Type bodyTy = closure->getSingleExpressionBody()->getType();
Type bodyTy = CS.getType(closure->getSingleExpressionBody());
CG.getConstraintSystem().setFavoredType(expr, bodyTy.getPointer());
CG.getConstraintSystem()
.addConstraint(ConstraintKind::Conversion, bodyTy,