Skip to content

Commit 62e825a

Browse files
authored
Merge pull request #6583 from rudkx/cs-typemap
Improve handling of types in constraint system.
2 parents 09e72e5 + 7f64b68 commit 62e825a

File tree

4 files changed

+167
-54
lines changed

4 files changed

+167
-54
lines changed

lib/Sema/CSApply.cpp

Lines changed: 83 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -470,9 +470,8 @@ namespace {
470470

471471
// Build a reference to the protocol requirement.
472472
Expr *base =
473-
cs.cacheType(TypeExpr::createImplicitHack(loc.getBaseNameLoc(),
474-
baseTy,
475-
ctx));
473+
TypeExpr::createImplicitHack(loc.getBaseNameLoc(), baseTy, ctx);
474+
cs.cacheExprTypes(base);
476475

477476
return buildMemberRef(base, openedType, SourceLoc(), decl,
478477
loc, openedFnType->getResult(),
@@ -778,6 +777,7 @@ namespace {
778777
// If the member is a constructor, verify that it can be legally
779778
// referenced from this base.
780779
if (auto ctor = dyn_cast<ConstructorDecl>(member)) {
780+
cs.setExprTypes(base);
781781
if (!tc.diagnoseInvalidDynamicConstructorReferences(base, memberLoc,
782782
baseMeta, ctor, SuppressDiagnostics))
783783
return nullptr;
@@ -1436,13 +1436,14 @@ namespace {
14361436
ConcreteDeclRef fnDeclRef(fn);
14371437
auto fnRef = new (tc.Context) DeclRefExpr(fnDeclRef, DeclNameLoc(loc),
14381438
/*Implicit=*/true);
1439-
cs.setType(fnRef, fn->getInterfaceType());
1439+
fnRef->setType(fn->getInterfaceType());
14401440
fnRef->setFunctionRefKind(FunctionRefKind::SingleApply);
1441+
cs.setExprTypes(value);
14411442
Expr *call = CallExpr::createImplicit(tc.Context, fnRef, { value }, { });
14421443
if (tc.typeCheckExpressionShallow(call, dc))
14431444
return nullptr;
14441445

1445-
cs.cacheType(call);
1446+
cs.cacheExprTypes(call);
14461447

14471448
// The return type of _bridgeErrorToNSError is formally
14481449
// 'AnyObject' to avoid stdlib-to-Foundation dependencies, but it's
@@ -1477,11 +1478,18 @@ namespace {
14771478
tc.conformsToProtocol(valueType, bridgedProto, cs.DC,
14781479
(ConformanceCheckFlags::InExpression|
14791480
ConformanceCheckFlags::Used))) {
1481+
cs.setExprTypes(value);
1482+
14801483
// Form the call.
1481-
return cs.cacheType(
1484+
auto result =
14821485
tc.callWitness(value, cs.DC, bridgedProto, *conformance,
14831486
tc.Context.Id_bridgeToObjectiveC,
1484-
{ }, diag::broken_bridged_to_objc_protocol));
1487+
{ }, diag::broken_bridged_to_objc_protocol);
1488+
1489+
if (result)
1490+
cs.cacheExprTypes(result);
1491+
1492+
return result;
14851493
}
14861494

14871495
// If there is an Error conformance, try bridging as an error.
@@ -1626,6 +1634,9 @@ namespace {
16261634
// Form the call and type-check it.
16271635
Expr *call = CallExpr::createImplicit(tc.Context, fnRef, args,
16281636
{ Identifier(), Identifier() });
1637+
cs.cacheSubExprTypes(call);
1638+
cs.setSubExprTypes(call);
1639+
16291640
if (tc.typeCheckExpressionShallow(call, dc))
16301641
return nullptr;
16311642

@@ -2078,6 +2089,8 @@ namespace {
20782089
member,
20792090
DeclNameLoc(expr->getStartLoc()),
20802091
/*Implicit=*/true);
2092+
cs.cacheSubExprTypes(memberRef);
2093+
cs.setSubExprTypes(memberRef);
20812094
bool failed = tc.typeCheckExpressionShallow(memberRef, cs.DC);
20822095
cs.cacheExprTypes(memberRef);
20832096
assert(!failed && "Could not reference string interpolation witness");
@@ -2189,12 +2202,21 @@ namespace {
21892202
if (!isa<TupleExpr>(expr->getArg()))
21902203
return nullptr;
21912204
auto tupleArg = cast<TupleExpr>(expr->getArg());
2192-
for (auto elt : tupleArg->getElements())
2205+
for (auto elt : tupleArg->getElements()) {
2206+
cs.setExprTypes(elt);
21932207
args.push_back(elt);
2208+
}
21942209
DeclName constrName(tc.getObjectLiteralConstructorName(expr));
2210+
2211+
cs.cacheExprTypes(base);
2212+
cs.setExprTypes(base);
2213+
21952214
Expr *semanticExpr = tc.callWitness(base, dc, proto, *conformance,
21962215
constrName, args,
21972216
diag::object_literal_broken_proto);
2217+
if (semanticExpr)
2218+
cs.cacheExprTypes(semanticExpr);
2219+
21982220
expr->setSemanticExpr(semanticExpr);
21992221
return expr;
22002222
}
@@ -2661,22 +2683,27 @@ namespace {
26612683
}
26622684

26632685
Type argType = TupleType::get(typeElements, tc.Context);
2664-
Expr *arg = cs.cacheType(
2686+
Expr *arg =
26652687
TupleExpr::create(tc.Context, SourceLoc(),
26662688
expr->getElements(),
26672689
names,
26682690
{ },
26692691
SourceLoc(), /*HasTrailingClosure=*/false,
26702692
/*Implicit=*/true,
2671-
argType));
2693+
argType);
2694+
2695+
cs.cacheExprTypes(typeRef);
2696+
cs.setExprTypes(typeRef);
2697+
26722698
Expr *result = tc.callWitness(typeRef, dc, arrayProto, *conformance,
26732699
name, arg, diag::array_protocol_broken);
26742700
if (!result)
26752701
return nullptr;
26762702

2703+
cs.cacheExprTypes(result);
2704+
26772705
expr->setSemanticExpr(result);
26782706
cs.setType(expr, arrayTy);
2679-
cs.cacheSubExprTypes(expr);
26802707

26812708
// If the array element type was defaulted, note that in the expression.
26822709
if (solution.DefaultedConstraints.count(cs.getConstraintLocator(expr)))
@@ -2734,25 +2761,28 @@ namespace {
27342761

27352762
Type argType = TupleType::get(typeElements, tc.Context);
27362763
Expr *arg =
2737-
cs.cacheType(
27382764
TupleExpr::create(tc.Context, expr->getLBracketLoc(),
27392765
expr->getElements(),
27402766
names,
27412767
{ },
27422768
expr->getRBracketLoc(),
27432769
/*HasTrailingClosure=*/false,
27442770
/*Implicit=*/false,
2745-
argType));
2771+
argType);
2772+
2773+
cs.cacheExprTypes(typeRef);
2774+
cs.setExprTypes(typeRef);
27462775

27472776
Expr *result = tc.callWitness(typeRef, dc, dictionaryProto,
27482777
*conformance, name, arg,
27492778
diag::dictionary_protocol_broken);
27502779
if (!result)
27512780
return nullptr;
27522781

2782+
cs.cacheExprTypes(result);
2783+
27532784
expr->setSemanticExpr(result);
27542785
cs.setType(expr, dictionaryTy);
2755-
cs.cacheSubExprTypes(expr);
27562786

27572787
// If the dictionary key or value type was defaulted, note that in the
27582788
// expression.
@@ -3244,8 +3274,11 @@ namespace {
32443274
if (*choice == 0) {
32453275
// Convert the subexpression.
32463276
Expr *sub = expr->getSubExpr();
3277+
3278+
cs.setExprTypes(sub);
32473279
if (tc.convertToType(sub, toType, cs.DC))
32483280
return nullptr;
3281+
cs.cacheExprTypes(sub);
32493282

32503283
expr->setSubExpr(sub);
32513284
cs.setType(expr, toType);
@@ -3528,11 +3561,11 @@ namespace {
35283561
bool invalid = tc.typeCheckExpression(callExpr, cs.DC,
35293562
TypeLoc::withoutLoc(valueType),
35303563
CTP_CannotFail);
3564+
cs.cacheExprTypes(callExpr);
3565+
35313566
(void) invalid;
35323567
assert(!invalid && "conversion cannot fail");
35333568

3534-
cs.cacheExprTypes(callExpr);
3535-
35363569
E->setSemanticExpr(callExpr);
35373570
return E;
35383571
}
@@ -4211,11 +4244,11 @@ getCallerDefaultArg(ConstraintSystem &cs, DeclContext *dc,
42114244
bool invalid = tc.typeCheckExpression(init, dc,
42124245
TypeLoc::withoutLoc(defArgType),
42134246
CTP_CannotFail);
4247+
cs.cacheExprTypes(init);
4248+
42144249
assert(!invalid && "conversion cannot fail");
42154250
(void)invalid;
42164251

4217-
cs.cacheExprTypes(init);
4218-
42194252
return {init, defArg.first};
42204253
}
42214254

@@ -4812,7 +4845,7 @@ Expr *ExprRewriter::coerceCallArguments(
48124845
// Total hack: In Swift 3 mode, argument labels are ignored when calling
48134846
// function type with a single Any parameter.
48144847
if (paramType->isAny()) {
4815-
if (auto tupleArgType = dyn_cast<TupleType>(arg->getType().getPointer())) {
4848+
if (auto tupleArgType = dyn_cast<TupleType>(cs.getType(arg).getPointer())) {
48164849
if (tupleArgType->getNumElements() == 1) {
48174850
matchCanFail = true;
48184851
}
@@ -6022,15 +6055,20 @@ Expr *ExprRewriter::convertLiteral(Expr *literal,
60226055
// Call the builtin conversion operation.
60236056
// FIXME: Bogus location info.
60246057
Expr *base =
6025-
cs.cacheType(TypeExpr::createImplicitHack(literal->getLoc(), type,
6026-
tc.Context));
6058+
TypeExpr::createImplicitHack(literal->getLoc(), type, tc.Context);
6059+
6060+
cs.cacheExprTypes(base);
6061+
cs.setExprTypes(base);
6062+
cs.setExprTypes(literal);
6063+
60276064
Expr *result = tc.callWitness(base, dc,
60286065
builtinProtocol, *builtinConformance,
60296066
builtinLiteralFuncName,
60306067
literal,
60316068
brokenBuiltinProtocolDiag);
60326069
if (result)
6033-
cs.setType(result, type);
6070+
cs.cacheExprTypes(result);
6071+
60346072
return result;
60356073
}
60366074

@@ -6081,14 +6119,18 @@ Expr *ExprRewriter::convertLiteral(Expr *literal,
60816119

60826120
// Convert the resulting expression to the final literal type.
60836121
// FIXME: Bogus location info.
6084-
Expr *base =
6085-
cs.cacheType(TypeExpr::createImplicitHack(literal->getLoc(), type,
6086-
tc.Context));
6122+
Expr *base = TypeExpr::createImplicitHack(literal->getLoc(), type,
6123+
tc.Context);
6124+
cs.cacheExprTypes(base);
6125+
cs.setExprTypes(base);
6126+
cs.setExprTypes(literal);
6127+
60876128
literal = tc.callWitness(base, dc,
60886129
protocol, *conformance, literalFuncName,
60896130
literal, brokenProtocolDiag);
60906131
if (literal)
6091-
cs.setType(literal, type);
6132+
cs.cacheExprTypes(literal);
6133+
60926134
return literal;
60936135
}
60946136

@@ -6321,7 +6363,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
63216363
assert(arg->getNumElements() == 2 && "should have two arguments");
63226364
auto nonescaping = arg->getElements()[0];
63236365
auto body = arg->getElements()[1];
6324-
auto bodyFnTy = body->getType()->castTo<FunctionType>();
6366+
auto bodyFnTy = cs.getType(body)->castTo<FunctionType>();
63256367
auto escapableType = bodyFnTy->getInput();
63266368
auto resultType = bodyFnTy->getResult();
63276369

@@ -6418,7 +6460,9 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
64186460
cs.setType(apply, fnType->getResult());
64196461
apply->setIsSuper(isSuper);
64206462

6463+
cs.setExprTypes(apply);
64216464
Expr *result = tc.substituteInputSugarTypeForResult(apply);
6465+
cs.cacheExprTypes(result);
64226466

64236467
// Try closing the existential, if there is one.
64246468
closeExistential(result, locator);
@@ -7131,13 +7175,8 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
71317175
// Construct an empty constraint system and solution.
71327176
ConstraintSystem cs(*this, dc, ConstraintSystemOptions());
71337177

7134-
cs.cacheExprTypes(base);
7135-
for (auto *e : arguments) {
7136-
cs.cacheExprTypes(e);
7137-
}
7138-
71397178
// Find the witness we need to use.
7140-
auto type = cs.getType(base);
7179+
auto type = base->getType();
71417180
assert(!type->hasTypeVariable() &&
71427181
"Building call to witness with unresolved base type!");
71437182

@@ -7164,7 +7203,7 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
71647203
// Form a reference to the witness itself.
71657204
Type openedFullType, openedType;
71667205
std::tie(openedFullType, openedType)
7167-
= cs.getTypeOfMemberReference(cs.getType(base), witness,
7206+
= cs.getTypeOfMemberReference(base->getType(), witness,
71687207
/*isTypeReference=*/false,
71697208
/*isDynamicResult=*/false,
71707209
FunctionRefKind::DoubleApply,
@@ -7177,7 +7216,7 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
71777216
auto argLabels = witness->getFullName().getArgumentNames();
71787217
if (arguments.size() == 1 &&
71797218
(isVariadicWitness(witness) ||
7180-
argumentNamesMatch(cs.getType(arguments[0]), argLabels))) {
7219+
argumentNamesMatch(arguments[0]->getType(), argLabels))) {
71817220
call = CallExpr::create(Context, unresolvedDot, arguments[0], { },
71827221
{ }, /*hasTrailingClosure=*/false,
71837222
/*implicit=*/true);
@@ -7203,18 +7242,18 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
72037242
/*implicit=*/true);
72047243
}
72057244

7206-
cs.cacheExprTypes(call);
7207-
72087245
// Add the conversion from the argument to the function parameter type.
72097246
cs.addConstraint(ConstraintKind::ArgumentTupleConversion,
7210-
cs.getType(call->getArg()),
7247+
call->getArg()->getType(),
72117248
openedType->castTo<FunctionType>()->getInput(),
72127249
cs.getConstraintLocator(call,
72137250
ConstraintLocator::ApplyArgument));
72147251

72157252
// Solve the system.
72167253
SmallVector<Solution, 1> solutions;
72177254

7255+
cs.cacheExprTypes(call);
7256+
72187257
// If the system failed to produce a solution, post any available diagnostics.
72197258
if (cs.solve(solutions) || solutions.size() != 1) {
72207259
cs.salvage(solutions, base);
@@ -7289,15 +7328,19 @@ Solution::convertBooleanTypeToBuiltinI1(Expr *expr, ConstraintLocator *locator)
72897328
builtinMethod,
72907329
DeclNameLoc(expr->getLoc()),
72917330
/*Implicit=*/true);
7331+
cs.cacheSubExprTypes(memberRef);
7332+
cs.setSubExprTypes(memberRef);
72927333
bool failed = tc.typeCheckExpressionShallow(memberRef, cs.DC);
7293-
cs.cacheType(memberRef);
7334+
cs.cacheExprTypes(memberRef);
72947335
assert(!failed && "Could not reference witness?");
72957336
(void)failed;
72967337

72977338
// Call the builtin method.
72987339
expr = CallExpr::createImplicit(ctx, memberRef, { }, { });
7340+
cs.cacheSubExprTypes(expr);
7341+
cs.setSubExprTypes(expr);
72997342
failed = tc.typeCheckExpressionShallow(expr, cs.DC);
7300-
cs.cacheType(expr);
7343+
cs.cacheExprTypes(expr);
73017344
assert(!failed && "Could not call witness?");
73027345
(void)failed;
73037346

lib/Sema/CSGen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,7 +2327,7 @@ namespace {
23272327
outputTy = fnType->getResult();
23282328
}
23292329
} else if (auto TE = dyn_cast<TypeExpr>(fnExpr)) {
2330-
outputTy = TE->getInstanceType();
2330+
outputTy = CS.getInstanceType(TE);
23312331
NominalTypeDecl *NTD = nullptr;
23322332

23332333
if (auto nominalType = outputTy->getAs<NominalType>()) {
@@ -2976,7 +2976,7 @@ Expr *ConstraintSystem::generateConstraintsShallow(Expr *expr) {
29762976
// Sanitize the expression.
29772977
expr = SanitizeExpr(getTypeChecker()).walkToExprPost(expr);
29782978

2979-
cacheExprTypes(expr);
2979+
cacheSubExprTypes(expr);
29802980

29812981
// Visit the top-level expression generating constraints.
29822982
ConstraintGenerator cg(*this);

0 commit comments

Comments
 (0)