Skip to content

Commit 2d20883

Browse files
committed
[CSDiag] FailureDiagnosis needs to account for the fact that expressions are sanitized
After calling `get{Possible}Type{s}WithoutApplying` types have to be re-cached afterwards because sanitizer (run as part of the constraint generator) can mutate AST to e.g. re-introduce member references. Resolves: rdar://problem/46497155 (cherry picked from commit 9ecc0ab)
1 parent 0eb516c commit 2d20883

File tree

1 file changed

+45
-22
lines changed

1 file changed

+45
-22
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,27 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
423423
const CalleeCandidateInfo &candidates,
424424
TCCOptions options = TCCOptions());
425425

426+
void getPossibleTypesOfExpressionWithoutApplying(
427+
Expr *&expr, DeclContext *dc, SmallPtrSetImpl<TypeBase *> &types,
428+
FreeTypeVariableBinding allowFreeTypeVariables =
429+
FreeTypeVariableBinding::Disallow,
430+
ExprTypeCheckListener *listener = nullptr) {
431+
CS.TC.getPossibleTypesOfExpressionWithoutApplying(
432+
expr, dc, types, allowFreeTypeVariables, listener);
433+
CS.cacheExprTypes(expr);
434+
}
435+
436+
Type getTypeOfExpressionWithoutApplying(
437+
Expr *&expr, DeclContext *dc, ConcreteDeclRef &referencedDecl,
438+
FreeTypeVariableBinding allowFreeTypeVariables =
439+
FreeTypeVariableBinding::Disallow,
440+
ExprTypeCheckListener *listener = nullptr) {
441+
auto type = CS.TC.getTypeOfExpressionWithoutApplying(expr, dc, referencedDecl,
442+
allowFreeTypeVariables, listener);
443+
CS.cacheExprTypes(expr);
444+
return type;
445+
}
446+
426447
/// Diagnose common failures due to applications of an argument list to an
427448
/// ApplyExpr or SubscriptExpr.
428449
bool diagnoseParameterErrors(CalleeCandidateInfo &CCI,
@@ -452,6 +473,10 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
452473
Type contextualType,
453474
ContextualTypePurpose CTP);
454475

476+
bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
477+
CalleeCandidateInfo &CCI,
478+
ArrayRef<Identifier> argLabels);
479+
455480
private:
456481
/// Validate potential contextual type for type-checking one of the
457482
/// sub-expressions, usually correct/valid types are the ones which
@@ -3194,10 +3219,9 @@ decomposeArgType(Type argType, ArrayRef<Identifier> argLabels) {
31943219
return result;
31953220
}
31963221

3197-
static bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
3198-
CalleeCandidateInfo &CCI,
3199-
ArrayRef<Identifier> argLabels,
3200-
ConstraintSystem &CS) {
3222+
bool FailureDiagnosis::diagnoseImplicitSelfErrors(
3223+
Expr *fnExpr, Expr *argExpr, CalleeCandidateInfo &CCI,
3224+
ArrayRef<Identifier> argLabels) {
32013225
// If candidate list is empty it means that problem is somewhere else,
32023226
// since we need to have candidates which might be shadowing other funcs.
32033227
if (CCI.empty() || !CCI[0].getDecl())
@@ -3251,8 +3275,7 @@ static bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
32513275
for (unsigned i = 0, e = argTuple->getNumElements(); i < e; ++i) {
32523276
ConcreteDeclRef ref = nullptr;
32533277
auto *el = argTuple->getElement(i);
3254-
auto typeResult =
3255-
TC.getTypeOfExpressionWithoutApplying(el, CS.DC, ref);
3278+
auto typeResult = getTypeOfExpressionWithoutApplying(el, CS.DC, ref);
32563279
if (!typeResult)
32573280
return false;
32583281
auto flags = ParameterTypeFlags().withInOut(typeResult->is<InOutType>());
@@ -4226,7 +4249,7 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
42264249
}
42274250

42284251
// Try to diagnose errors related to the use of implicit self reference.
4229-
if (diagnoseImplicitSelfErrors(fnExpr, argExpr, CCI, argLabels, CS))
4252+
if (diagnoseImplicitSelfErrors(fnExpr, argExpr, CCI, argLabels))
42304253
return true;
42314254

42324255
if (diagnoseInstanceMethodAsCurriedMemberOnType(CCI, fnExpr, argExpr))
@@ -4368,7 +4391,7 @@ bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
43684391
ConcreteDeclRef decl = nullptr;
43694392
message = diag::cannot_subscript_with_index;
43704393

4371-
if (CS.TC.getTypeOfExpressionWithoutApplying(expr, CS.DC, decl))
4394+
if (getTypeOfExpressionWithoutApplying(expr, CS.DC, decl))
43724395
return false;
43734396

43744397
// If we are down to a single candidate but with an unresolved
@@ -4932,7 +4955,7 @@ bool FailureDiagnosis::diagnoseTrailingClosureErrors(ApplyExpr *callExpr) {
49324955
if (currentType->hasTypeVariable() || currentType->hasUnresolvedType()) {
49334956
auto contextualType = CS.getContextualType();
49344957
CallResultListener listener(contextualType);
4935-
CS.TC.getPossibleTypesOfExpressionWithoutApplying(
4958+
getPossibleTypesOfExpressionWithoutApplying(
49364959
fnExpr, CS.DC, possibleTypes, FreeTypeVariableBinding::UnresolvedType,
49374960
&listener);
49384961

@@ -5037,9 +5060,9 @@ bool FailureDiagnosis::diagnoseCallContextualConversionErrors(
50375060
auto &TC = CS.TC;
50385061
auto *DC = CS.DC;
50395062

5040-
auto typeCheckExpr = [](TypeChecker &TC, Expr *expr, DeclContext *DC,
5041-
SmallPtrSetImpl<TypeBase *> &types) {
5042-
TC.getPossibleTypesOfExpressionWithoutApplying(
5063+
auto typeCheckExpr = [&](TypeChecker &TC, Expr *expr, DeclContext *DC,
5064+
SmallPtrSetImpl<TypeBase *> &types) {
5065+
getPossibleTypesOfExpressionWithoutApplying(
50435066
expr, DC, types, FreeTypeVariableBinding::Disallow);
50445067
};
50455068

@@ -5165,14 +5188,14 @@ bool FailureDiagnosis::diagnoseSubscriptMisuse(ApplyExpr *callExpr) {
51655188
// unresolved result let's not re-typecheck the function expression,
51665189
// because it might produce unrelated diagnostics due to lack of
51675190
// contextual information.
5168-
static bool shouldTypeCheckFunctionExpr(TypeChecker &TC, DeclContext *DC,
5191+
static bool shouldTypeCheckFunctionExpr(FailureDiagnosis &FD, DeclContext *DC,
51695192
Expr *fnExpr) {
51705193
if (!isa<UnresolvedDotExpr>(fnExpr))
51715194
return true;
51725195

51735196
SmallPtrSet<TypeBase *, 4> fnTypes;
5174-
TC.getPossibleTypesOfExpressionWithoutApplying(fnExpr, DC, fnTypes,
5175-
FreeTypeVariableBinding::UnresolvedType);
5197+
FD.getPossibleTypesOfExpressionWithoutApplying(
5198+
fnExpr, DC, fnTypes, FreeTypeVariableBinding::UnresolvedType);
51765199

51775200
if (fnTypes.size() == 1) {
51785201
// Some member types depend on the arguments to produce a result type,
@@ -5232,7 +5255,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
52325255
auto *fnExpr = callExpr->getFn();
52335256
auto originalFnType = CS.getType(callExpr->getFn());
52345257

5235-
if (shouldTypeCheckFunctionExpr(CS.TC, CS.DC, fnExpr)) {
5258+
if (shouldTypeCheckFunctionExpr(*this, CS.DC, fnExpr)) {
52365259

52375260
// If we are misusing a subscript, diagnose that and provide a fixit.
52385261
// We diagnose this here to have enough context to offer an appropriate fixit.
@@ -5269,7 +5292,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
52695292
fnExpr = callExpr->getFn();
52705293

52715294
SmallPtrSet<TypeBase *, 4> types;
5272-
CS.TC.getPossibleTypesOfExpressionWithoutApplying(fnExpr, CS.DC, types);
5295+
getPossibleTypesOfExpressionWithoutApplying(fnExpr, CS.DC, types);
52735296

52745297
auto isFunctionType = [getFuncType](Type type) -> bool {
52755298
return type && getFuncType(type)->is<AnyFunctionType>();
@@ -5309,7 +5332,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
53095332
"unexpected declaration reference");
53105333

53115334
ConcreteDeclRef decl = nullptr;
5312-
Type type = CS.TC.getTypeOfExpressionWithoutApplying(
5335+
Type type = getTypeOfExpressionWithoutApplying(
53135336
fnExpr, CS.DC, decl, FreeTypeVariableBinding::UnresolvedType,
53145337
&listener);
53155338

@@ -5893,7 +5916,7 @@ bool FailureDiagnosis::visitAssignExpr(AssignExpr *assignExpr) {
58935916
ExprTypeSaverAndEraser eraser(srcExpr);
58945917

58955918
ConcreteDeclRef ref = nullptr;
5896-
auto type = CS.TC.getTypeOfExpressionWithoutApplying(srcExpr, CS.DC, ref);
5919+
auto type = getTypeOfExpressionWithoutApplying(srcExpr, CS.DC, ref);
58975920

58985921
if (type && !type->isEqual(contextualType))
58995922
return diagnoseContextualConversionError(
@@ -6391,7 +6414,7 @@ bool FailureDiagnosis::diagnoseClosureExpr(
63916414
// diagnose situations where contextual type expected one result
63926415
// type but actual closure produces a different one without explicitly
63936416
// declaring it (e.g. by using anonymous parameters).
6394-
auto type = CS.TC.getTypeOfExpressionWithoutApplying(
6417+
auto type = getTypeOfExpressionWithoutApplying(
63956418
closure, CS.DC, decl, FreeTypeVariableBinding::Disallow);
63966419

63976420
if (type && resultTypeProcessor(type, expectedResultType))
@@ -6900,7 +6923,7 @@ bool FailureDiagnosis::visitKeyPathExpr(KeyPathExpr *KPE) {
69006923
KeyPathListener listener(klass, parentType, rootType);
69016924
ConcreteDeclRef concreteDecl;
69026925

6903-
auto derivedType = CS.TC.getTypeOfExpressionWithoutApplying(
6926+
auto derivedType = getTypeOfExpressionWithoutApplying(
69046927
expr, CS.DC, concreteDecl, FreeTypeVariableBinding::Disallow,
69056928
&listener);
69066929

@@ -8058,7 +8081,7 @@ diagnoseAmbiguousMultiStatementClosure(ClosureExpr *closure) {
80588081
// successfully type-checked its type cleanup is going to be disabled
80598082
// (we are allowing unresolved types), and as a side-effect it might
80608083
// also be transformed e.g. OverloadedDeclRefExpr -> DeclRefExpr.
8061-
auto type = CS.TC.getTypeOfExpressionWithoutApplying(
8084+
auto type = getTypeOfExpressionWithoutApplying(
80628085
resultExpr, CS.DC, decl, FreeTypeVariableBinding::UnresolvedType);
80638086
if (type)
80648087
resultType = type;

0 commit comments

Comments
 (0)