Skip to content

Commit 79d7064

Browse files
authored
Merge pull request #13664 from xedin/finalize-expr-type-cache
[ConstraintSystem] Only set types on expressions in presence of solution
2 parents bb4fe4e + 8c17b92 commit 79d7064

18 files changed

+184
-137
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,13 +3867,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
38673867

38683868
static bool getPositionInTupleExpr(DeclContext &DC, Expr *Target,
38693869
TupleExpr *Tuple, unsigned &Pos,
3870-
bool &HasName,
3871-
llvm::SmallVectorImpl<Type> &TupleEleTypes) {
3870+
bool &HasName) {
38723871
auto &SM = DC.getASTContext().SourceMgr;
38733872
Pos = 0;
38743873
for (auto E : Tuple->getElements()) {
38753874
if (SM.isBeforeInBuffer(E->getEndLoc(), Target->getStartLoc())) {
3876-
TupleEleTypes.push_back(E->getType());
38773875
Pos ++;
38783876
continue;
38793877
}
@@ -3974,36 +3972,65 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
39743972
}
39753973
}
39763974

3977-
static bool collectPossibleArgTypes(DeclContext &DC, CallExpr *CallE, Expr *CCExpr,
3978-
SmallVectorImpl<Type> &PossibleTypes,
3979-
unsigned &Position, bool &HasName,
3980-
bool RemoveUnlikelyOverloads) {
3981-
if (auto Ty = CallE->getFn()->getType()) {
3982-
if (auto FT = Ty->getAs<FunctionType>()) {
3983-
PossibleTypes.push_back(FT->getInput());
3975+
static bool collectionInputTypes(DeclContext &DC, CallExpr *callExpr,
3976+
SmallVectorImpl<Type> &possibleTypes) {
3977+
auto *fnExpr = callExpr->getFn();
3978+
3979+
if (auto type = fnExpr->getType()) {
3980+
if (auto *funcType = type->getAs<AnyFunctionType>())
3981+
possibleTypes.push_back(funcType->getInput());
3982+
} else if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
3983+
if (auto *decl = DRE->getDecl()) {
3984+
auto declType = decl->getInterfaceType();
3985+
if (auto *funcType = declType->getAs<AnyFunctionType>())
3986+
possibleTypes.push_back(funcType->getInput());
39843987
}
3985-
}
3986-
if (auto TAG = dyn_cast<TupleExpr>(CallE->getArg())) {
3987-
llvm::SmallVector<Type, 3> TupleEleTypesBeforeTarget;
3988-
if (!getPositionInTupleExpr(DC, CCExpr, TAG, Position, HasName,
3989-
TupleEleTypesBeforeTarget))
3990-
return false;
3991-
if (PossibleTypes.empty() &&
3992-
!typeCheckUnresolvedExpr(DC, CallE->getArg(), CallE, PossibleTypes))
3993-
return false;
3994-
if (RemoveUnlikelyOverloads) {
3995-
removeUnlikelyOverloads(PossibleTypes, TupleEleTypesBeforeTarget, &DC);
3996-
return !PossibleTypes.empty();
3988+
} else if (auto *OSRE = dyn_cast<OverloadSetRefExpr>(fnExpr)) {
3989+
for (auto *decl : OSRE->getDecls()) {
3990+
auto declType = decl->getInterfaceType();
3991+
if (auto *funcType = declType->getAs<AnyFunctionType>())
3992+
possibleTypes.push_back(funcType->getInput());
39973993
}
3998-
} else if (isa<ParenExpr>(CallE->getArg())) {
3999-
Position = 0;
4000-
HasName = false;
4001-
if (PossibleTypes.empty() &&
4002-
!typeCheckUnresolvedExpr(DC, CallE->getArg(), CallE, PossibleTypes))
3994+
} else {
3995+
ConcreteDeclRef ref = nullptr;
3996+
auto fnType = getTypeOfCompletionContextExpr(DC.getASTContext(),
3997+
&DC, CompletionTypeCheckKind::Normal,
3998+
fnExpr, ref);
3999+
4000+
if (!fnType)
40034001
return false;
4004-
} else
4002+
4003+
if (auto *AFT = (*fnType)->getAs<AnyFunctionType>())
4004+
possibleTypes.push_back(AFT->getInput());
4005+
}
4006+
4007+
return !possibleTypes.empty();
4008+
}
4009+
4010+
static bool collectPossibleArgTypes(DeclContext &DC, CallExpr *CallE,
4011+
Expr *CCExpr,
4012+
SmallVectorImpl<Type> &PossibleTypes,
4013+
unsigned &Position, bool &HasName) {
4014+
if (!collectionInputTypes(DC, CallE, PossibleTypes))
40054015
return false;
4006-
return true;
4016+
4017+
if (auto *tuple = dyn_cast<TupleExpr>(CallE->getArg())) {
4018+
for (unsigned i = 0, n = tuple->getNumElements(); i != n; ++i) {
4019+
if (isa<CodeCompletionExpr>(tuple->getElement(i))) {
4020+
HasName = !tuple->getElementName(i).empty();
4021+
Position = i;
4022+
return true;
4023+
}
4024+
}
4025+
4026+
return getPositionInTupleExpr(DC, CCExpr, tuple, Position, HasName);
4027+
} else if (auto *paren = dyn_cast<ParenExpr>(CallE->getArg())) {
4028+
HasName = false;
4029+
Position = 0;
4030+
return true;
4031+
}
4032+
4033+
return false;
40074034
}
40084035

40094036
static bool
@@ -4014,7 +4041,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
40144041
unsigned Position;
40154042
bool HasName;
40164043
if (collectPossibleArgTypes(DC, CallE, CCExpr, PossibleTypes, Position,
4017-
HasName, true)) {
4044+
HasName)) {
40184045
collectArgumentExpectation(Position, HasName, PossibleTypes,
40194046
CCExpr->getStartLoc(), ExpectedTypes, ExpectedNames);
40204047
return !ExpectedTypes.empty() || !ExpectedNames.empty();
@@ -4026,10 +4053,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
40264053
SmallVector<Type, 2> PossibleTypes;
40274054
unsigned Position;
40284055
bool HasName;
4029-
return collectPossibleArgTypes(DC, CallE, CCExpr, PossibleTypes, Position,
4030-
HasName, true) &&
4031-
lookupArgCompletionsAtPosition(Position, HasName, PossibleTypes,
4032-
CCExpr->getStartLoc());
4056+
bool hasPossibleArgTypes = collectPossibleArgTypes(DC, CallE, CCExpr,
4057+
PossibleTypes, Position,
4058+
HasName);
4059+
bool hasCompletions = lookupArgCompletionsAtPosition(Position, HasName,
4060+
PossibleTypes,
4061+
CCExpr->getStartLoc());
4062+
4063+
return hasPossibleArgTypes && hasCompletions;
40334064
}
40344065

40354066
void getTypeContextEnumElementCompletions(SourceLoc Loc) {
@@ -5062,7 +5093,13 @@ class CodeCompletionTypeContextAnalyzer {
50625093
if (SM.isBeforeInBuffer(AE->getEqualLoc(), ParsedExpr->getStartLoc())) {
50635094

50645095
// The destination is of the expected type.
5065-
Callback(AE->getDest()->getType());
5096+
auto *destExpr = AE->getDest();
5097+
if (auto type = destExpr->getType()) {
5098+
Callback(type);
5099+
} else if (auto *DRE = dyn_cast<DeclRefExpr>(destExpr)) {
5100+
if (auto *decl = DRE->getDecl())
5101+
Callback(decl->getInterfaceType());
5102+
}
50665103
}
50675104
break;
50685105
}
@@ -5436,7 +5473,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
54365473
}
54375474
case CompletionKind::AssignmentRHS : {
54385475
SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
5439-
if (auto destType = AssignmentExpr->getDest()->getType())
5476+
if (auto destType = ParsedExpr->getType())
54405477
Lookup.setExpectedTypes(destType->getRValueType());
54415478
Lookup.getValueCompletionsInDeclContext(Loc, DefaultFilter);
54425479
break;

lib/Sema/CSApply.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,10 +2458,9 @@ namespace {
24582458
}
24592459

24602460
Expr *visitTypeExpr(TypeExpr *expr) {
2461-
auto toType = simplifyType(expr->getTypeLoc().getType());
2461+
auto toType = simplifyType(cs.getType(expr->getTypeLoc()));
24622462
expr->getTypeLoc().setType(toType, /*validated=*/true);
24632463
cs.setType(expr, MetatypeType::get(toType));
2464-
24652464
return expr;
24662465
}
24672466

@@ -3121,7 +3120,7 @@ namespace {
31213120
Expr *visitIsExpr(IsExpr *expr) {
31223121
// Turn the subexpression into an rvalue.
31233122
auto &tc = cs.getTypeChecker();
3124-
auto toType = simplifyType(expr->getCastTypeLoc().getType());
3123+
auto toType = simplifyType(cs.getType(expr->getCastTypeLoc()));
31253124
auto sub = cs.coerceToRValue(expr->getSubExpr());
31263125

31273126
checkForImportedUsedConformances(toType);
@@ -3193,6 +3192,7 @@ namespace {
31933192
sub, expr->getLoc(), SourceLoc(),
31943193
TypeLoc::withoutLoc(toType));
31953194
cs.setType(cast, toOptType);
3195+
cs.setType(cast->getCastTypeLoc(), toType);
31963196
if (expr->isImplicit())
31973197
cast->setImplicit();
31983198

@@ -3470,7 +3470,7 @@ namespace {
34703470

34713471
Expr *visitCoerceExpr(CoerceExpr *expr, Optional<unsigned> choice) {
34723472
// Simplify the type we're casting to.
3473-
auto toType = simplifyType(expr->getCastTypeLoc().getType());
3473+
auto toType = simplifyType(cs.getType(expr->getCastTypeLoc()));
34743474
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
34753475
checkForImportedUsedConformances(toType);
34763476

@@ -3556,7 +3556,7 @@ namespace {
35563556
// Most of the logic for dealing with ForcedCheckedCastExpr.
35573557
Expr *handleForcedCheckedCastExpr(ForcedCheckedCastExpr *expr) {
35583558
// Simplify the type we're casting to.
3559-
auto toType = simplifyType(expr->getCastTypeLoc().getType());
3559+
auto toType = simplifyType(cs.getType(expr->getCastTypeLoc()));
35603560
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
35613561
checkForImportedUsedConformances(toType);
35623562

@@ -3599,6 +3599,7 @@ namespace {
35993599
auto *result = new (tc.Context) CoerceExpr(sub, expr->getLoc(),
36003600
expr->getCastTypeLoc());
36013601
cs.setType(result, toType);
3602+
cs.setType(result->getCastTypeLoc(), toType);
36023603
unsigned disjunctionChoice =
36033604
(castKind == CheckedCastKind::Coercion ? 0 : 1);
36043605
return visitCoerceExpr(result, disjunctionChoice);
@@ -3636,7 +3637,7 @@ namespace {
36363637
Expr *handleConditionalCheckedCastExpr(ConditionalCheckedCastExpr *expr,
36373638
bool isInsideIsExpr = false) {
36383639
// Simplify the type we're casting to.
3639-
auto toType = simplifyType(expr->getCastTypeLoc().getType());
3640+
auto toType = simplifyType(cs.getType(expr->getCastTypeLoc()));
36403641
checkForImportedUsedConformances(toType);
36413642
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
36423643

@@ -3674,6 +3675,7 @@ namespace {
36743675
auto *coerce = new (tc.Context) CoerceExpr(sub, expr->getLoc(),
36753676
expr->getCastTypeLoc());
36763677
cs.setType(coerce, toType);
3678+
cs.setType(coerce->getCastTypeLoc(), toType);
36773679
unsigned disjunctionChoice =
36783680
(castKind == CheckedCastKind::Coercion ? 0 : 1);
36793681
Expr *result = visitCoerceExpr(coerce, disjunctionChoice);
@@ -4451,11 +4453,11 @@ namespace {
44514453
bool allIndexesHashable = true;
44524454
ArrayRef<TupleTypeElt> indexTypes;
44534455
TupleTypeElt singleIndexTypeBuf;
4454-
if (auto tup = component.getIndexExpr()->getType()
4456+
if (auto tup = cs.getType(component.getIndexExpr())
44554457
->getAs<TupleType>()) {
44564458
indexTypes = tup->getElements();
44574459
} else {
4458-
singleIndexTypeBuf = component.getIndexExpr()->getType();
4460+
singleIndexTypeBuf = cs.getType(component.getIndexExpr());
44594461
indexTypes = singleIndexTypeBuf;
44604462
}
44614463

@@ -6192,13 +6194,14 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
61926194
// swap the order so that we load first and force the result.
61936195
cs.propagateLValueAccessKind(expr, AccessKind::Read);
61946196
if (auto *forceExpr = dyn_cast<ForceValueExpr>(expr)) {
6195-
fromType = forceExpr->getSubExpr()->getType()->getRValueType();
6197+
fromType = cs.getType(forceExpr->getSubExpr())->getRValueType();
61966198
auto *loadExpr = cs.cacheType(
61976199
new (tc.Context) LoadExpr(forceExpr->getSubExpr(), fromType));
61986200
auto *newForceValue = new (tc.Context)
61996201
ForceValueExpr(loadExpr, forceExpr->getLoc(),
62006202
forceExpr->isForceOfImplicitlyUnwrappedOptional());
6201-
cs.setType(newForceValue, loadExpr->getType()->getOptionalObjectType());
6203+
cs.setType(newForceValue,
6204+
cs.getType(loadExpr)->getOptionalObjectType());
62026205
expr = newForceValue;
62036206
} else {
62046207
expr = cs.cacheType(new (tc.Context)
@@ -7542,6 +7545,7 @@ namespace {
75427545
} else {
75437546
// For other closures, type-check the body once we've finished with
75447547
// the expression.
7548+
cs.setExprTypes(closure);
75457549
ClosuresToTypeCheck.push_back(closure);
75467550
}
75477551

lib/Sema/CSDiag.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,6 +2152,8 @@ static void eraseOpenedExistentials(Expr *&expr, ConstraintSystem &CS) {
21522152
return type;
21532153
});
21542154
CS.setType(expr, type);
2155+
// Set new type to the expression directly.
2156+
expr->setType(type);
21552157

21562158
return expr;
21572159
}
@@ -6075,7 +6077,7 @@ bool FailureDiagnosis::visitInOutExpr(InOutExpr *IOE) {
60756077
bool FailureDiagnosis::visitCoerceExpr(CoerceExpr *CE) {
60766078
// Coerce the input to whatever type is specified by the CoerceExpr.
60776079
auto expr = typeCheckChildIndependently(CE->getSubExpr(),
6078-
CE->getCastTypeLoc().getType(),
6080+
CS.getType(CE->getCastTypeLoc()),
60796081
CTP_CoerceOperand);
60806082
if (!expr)
60816083
return true;
@@ -7920,12 +7922,13 @@ static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
79207922
// `Pair<Any, Any>`.
79217923
// Right now we only handle this when the type that's at fault is the
79227924
// top-level type passed to this function.
7923-
if (loc.getType().isNull()) {
7924-
return;
7925-
}
7926-
7925+
auto type = loc.getType();
7926+
if (!type)
7927+
type = cs.getType(loc);
7928+
79277929
ArrayRef<Type> genericArgs;
7928-
if (auto *boundGenericTy = loc.getType()->getAs<BoundGenericType>()) {
7930+
7931+
if (auto *boundGenericTy = type->getAs<BoundGenericType>()) {
79297932
if (boundGenericTy->getDecl() == FoundDecl)
79307933
genericArgs = boundGenericTy->getGenericArgs();
79317934
}

lib/Sema/CSGen.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,7 @@ namespace {
13621362

13631363
auto locator = CS.getConstraintLocator(E);
13641364
type = CS.openUnboundGenericType(type, locator);
1365-
E->getTypeLoc().setType(type, /*validated=*/true);
1365+
CS.setType(E->getTypeLoc(), type);
13661366
return MetatypeType::get(type);
13671367
}
13681368

@@ -2534,7 +2534,7 @@ namespace {
25342534
// Open the type we're casting to.
25352535
auto toType = CS.openUnboundGenericType(expr->getCastTypeLoc().getType(),
25362536
CS.getConstraintLocator(expr));
2537-
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
2537+
CS.setType(expr->getCastTypeLoc(), toType);
25382538

25392539
auto fromType = CS.getType(fromExpr);
25402540
auto locator = CS.getConstraintLocator(expr);
@@ -2563,7 +2563,7 @@ namespace {
25632563
// Open the type we're casting to.
25642564
auto toType = CS.openUnboundGenericType(expr->getCastTypeLoc().getType(),
25652565
CS.getConstraintLocator(expr));
2566-
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
2566+
CS.setType(expr->getCastTypeLoc(), toType);
25672567

25682568
auto fromType = CS.getType(expr->getSubExpr());
25692569
auto locator = CS.getConstraintLocator(expr);
@@ -2597,7 +2597,7 @@ namespace {
25972597
// Open the type we're casting to.
25982598
auto toType = CS.openUnboundGenericType(expr->getCastTypeLoc().getType(),
25992599
CS.getConstraintLocator(expr));
2600-
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
2600+
CS.setType(expr->getCastTypeLoc(), toType);
26012601

26022602
auto fromType = CS.getType(fromExpr);
26032603
auto locator = CS.getConstraintLocator(expr);
@@ -2626,7 +2626,7 @@ namespace {
26262626
// FIXME: Locator for the cast type?
26272627
auto toType = CS.openUnboundGenericType(expr->getCastTypeLoc().getType(),
26282628
CS.getConstraintLocator(expr));
2629-
expr->getCastTypeLoc().setType(toType, /*validated=*/true);
2629+
CS.setType(expr->getCastTypeLoc(), toType);
26302630

26312631
// Add a checked cast constraint.
26322632
auto fromType = CS.getType(expr->getSubExpr());
@@ -3216,6 +3216,7 @@ namespace {
32163216

32173217
auto *TE = TypeExpr::createImplicit(joinTy, CS.getASTContext());
32183218
CS.cacheType(TE);
3219+
CS.setType(TE->getTypeLoc(), joinTy);
32193220

32203221
auto *DSE = new (CS.getASTContext())
32213222
DotSelfExpr(TE, SourceLoc(), SourceLoc(), CS.getType(TE));
@@ -3464,6 +3465,7 @@ bool swift::typeCheckUnresolvedExpr(DeclContext &DC,
34643465
SmallVectorImpl<Type> &PossibleTypes) {
34653466
PrettyStackTraceExpr stackTrace(DC.getASTContext(),
34663467
"type-checking unresolved member", Parent);
3468+
34673469
ConstraintSystemOptions Options = ConstraintSystemFlags::AllowFixes;
34683470
auto *TC = static_cast<TypeChecker*>(DC.getASTContext().getLazyResolver());
34693471
ConstraintSystem CS(*TC, &DC, Options);
@@ -3481,7 +3483,7 @@ bool swift::typeCheckUnresolvedExpr(DeclContext &DC,
34813483
}
34823484

34833485
SmallVector<Solution, 3> solutions;
3484-
if (CS.solve(Parent, solutions, FreeTypeVariableBinding::Allow)) {
3486+
if (CS.solve(Parent, solutions, FreeTypeVariableBinding::UnresolvedType)) {
34853487
return false;
34863488
}
34873489

0 commit comments

Comments
 (0)