Skip to content

Commit 24e5778

Browse files
committed
[Diagnostics] Switch from vector to set to avoid storing duplicate solution types
This allows callees of `getPossibleTypesOfExpressionWithoutApplying` to get only unique types from the re-run of the solver. (cherry picked from commit 7500c6e)
1 parent 9f28451 commit 24e5778

File tree

3 files changed

+16
-14
lines changed

3 files changed

+16
-14
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2803,7 +2803,8 @@ bool FailureDiagnosis::diagnoseContextualConversionError(
28032803
auto exprType = recheckedExpr ? CS.getType(recheckedExpr) : Type();
28042804

28052805
// If it failed and diagnosed something, then we're done.
2806-
if (!exprType) return true;
2806+
if (!exprType)
2807+
return CS.TC.Diags.hadAnyError();
28072808

28082809
// If we contextually had an inout type, and got a non-lvalue result, then
28092810
// we fail with a mutability error.
@@ -5263,7 +5264,7 @@ bool FailureDiagnosis::diagnoseTrailingClosureErrors(ApplyExpr *callExpr) {
52635264
}
52645265
};
52655266

5266-
SmallVector<Type, 4> possibleTypes;
5267+
SmallPtrSet<TypeBase *, 4> possibleTypes;
52675268
auto currentType = CS.getType(fnExpr);
52685269

52695270
// If current type has type variables or unresolved types
@@ -5283,10 +5284,10 @@ bool FailureDiagnosis::diagnoseTrailingClosureErrors(ApplyExpr *callExpr) {
52835284
return diagnoseContextualConversionError(callExpr, contextualType,
52845285
CS.getContextualTypePurpose());
52855286
} else {
5286-
possibleTypes.push_back(currentType);
5287+
possibleTypes.insert(currentType.getPointer());
52875288
}
52885289

5289-
for (auto type : possibleTypes) {
5290+
for (Type type : possibleTypes) {
52905291
auto *fnType = type->getAs<AnyFunctionType>();
52915292
if (!fnType)
52925293
continue;
@@ -5377,7 +5378,7 @@ bool FailureDiagnosis::diagnoseCallContextualConversionErrors(
53775378
auto *DC = CS.DC;
53785379

53795380
auto typeCheckExpr = [](TypeChecker &TC, Expr *expr, DeclContext *DC,
5380-
SmallVectorImpl<Type> &types,
5381+
SmallPtrSetImpl<TypeBase *> &types,
53815382
Type contextualType = Type()) {
53825383
CalleeListener listener(contextualType);
53835384
TC.getPossibleTypesOfExpressionWithoutApplying(
@@ -5387,7 +5388,7 @@ bool FailureDiagnosis::diagnoseCallContextualConversionErrors(
53875388
// First let's type-check expression without contextual type, and
53885389
// see if that's going to produce a type, if so, let's type-check
53895390
// again, this time using given contextual type.
5390-
SmallVector<Type, 4> withoutContextual;
5391+
SmallPtrSet<TypeBase *, 4> withoutContextual;
53915392
typeCheckExpr(TC, callExpr, DC, withoutContextual);
53925393

53935394
// If there are no types returned, it means that problem was
@@ -5396,12 +5397,13 @@ bool FailureDiagnosis::diagnoseCallContextualConversionErrors(
53965397
if (withoutContextual.empty())
53975398
return false;
53985399

5399-
SmallVector<Type, 4> withContextual;
5400+
SmallPtrSet<TypeBase *, 4> withContextual;
54005401
typeCheckExpr(TC, callExpr, DC, withContextual, contextualType);
54015402
// If type-checking with contextual type didn't produce any results
54025403
// it means that we have a contextual mismatch.
5403-
if (withContextual.empty())
5404+
if (withContextual.empty()) {
54045405
return diagnoseContextualConversionError(callExpr, contextualType, CTP);
5406+
}
54055407

54065408
// If call produces a single type when type-checked with contextual
54075409
// expression, it means that the problem is elsewhere, any other
@@ -5420,15 +5422,15 @@ static bool shouldTypeCheckFunctionExpr(TypeChecker &TC, DeclContext *DC,
54205422
if (!isa<UnresolvedDotExpr>(fnExpr))
54215423
return true;
54225424

5423-
SmallVector<Type, 4> fnTypes;
5425+
SmallPtrSet<TypeBase *, 4> fnTypes;
54245426
TC.getPossibleTypesOfExpressionWithoutApplying(fnExpr, DC, fnTypes,
54255427
FreeTypeVariableBinding::UnresolvedType);
54265428

54275429
if (fnTypes.size() == 1) {
54285430
// Some member types depend on the arguments to produce a result type,
54295431
// type-checking such expressions without associated arguments is
54305432
// going to produce unrelated diagnostics.
5431-
if (auto fn = fnTypes[0]->getAs<AnyFunctionType>()) {
5433+
if (auto fn = (*fnTypes.begin())->getAs<AnyFunctionType>()) {
54325434
auto resultType = fn->getResult();
54335435
if (resultType->hasUnresolvedType() || resultType->hasTypeVariable())
54345436
return false;
@@ -5483,7 +5485,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
54835485
isa<UnresolvedDotExpr>(callExpr->getFn())) {
54845486
fnExpr = callExpr->getFn();
54855487

5486-
SmallVector<Type, 4> types;
5488+
SmallPtrSet<TypeBase *, 4> types;
54875489
CS.TC.getPossibleTypesOfExpressionWithoutApplying(fnExpr, CS.DC, types);
54885490

54895491
auto isFunctionType = [getFuncType](Type type) -> bool {

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,7 +2010,7 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
20102010
}
20112011

20122012
void TypeChecker::getPossibleTypesOfExpressionWithoutApplying(
2013-
Expr *&expr, DeclContext *dc, SmallVectorImpl<Type> &types,
2013+
Expr *&expr, DeclContext *dc, SmallPtrSetImpl<TypeBase *> &types,
20142014
FreeTypeVariableBinding allowFreeTypeVariables,
20152015
ExprTypeCheckListener *listener) {
20162016
PrettyStackTraceExpr stackTrace(Context, "type-checking", expr);
@@ -2044,7 +2044,7 @@ void TypeChecker::getPossibleTypesOfExpressionWithoutApplying(
20442044
for (auto &solution : viable) {
20452045
auto exprType = solution.simplifyType(cs.getType(expr));
20462046
assert(exprType && !exprType->hasTypeVariable());
2047-
types.push_back(exprType);
2047+
types.insert(exprType.getPointer());
20482048
}
20492049
}
20502050

lib/Sema/TypeChecker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1745,7 +1745,7 @@ class TypeChecker final : public LazyResolver {
17451745
ExprTypeCheckListener *listener = nullptr);
17461746

17471747
void getPossibleTypesOfExpressionWithoutApplying(
1748-
Expr *&expr, DeclContext *dc, SmallVectorImpl<Type> &types,
1748+
Expr *&expr, DeclContext *dc, SmallPtrSetImpl<TypeBase *> &types,
17491749
FreeTypeVariableBinding allowFreeTypeVariables =
17501750
FreeTypeVariableBinding::Disallow,
17511751
ExprTypeCheckListener *listener = nullptr);

0 commit comments

Comments
 (0)