Skip to content

Commit c0f5711

Browse files
committed
[ConstraintSystem] Don't apply types to expressions until solution is found
Resolves: rdar://problem/36744895
1 parent c67cd28 commit c0f5711

14 files changed

+142
-114
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: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4451,11 +4451,11 @@ namespace {
44514451
bool allIndexesHashable = true;
44524452
ArrayRef<TupleTypeElt> indexTypes;
44534453
TupleTypeElt singleIndexTypeBuf;
4454-
if (auto tup = component.getIndexExpr()->getType()
4454+
if (auto tup = cs.getType(component.getIndexExpr())
44554455
->getAs<TupleType>()) {
44564456
indexTypes = tup->getElements();
44574457
} else {
4458-
singleIndexTypeBuf = component.getIndexExpr()->getType();
4458+
singleIndexTypeBuf = cs.getType(component.getIndexExpr());
44594459
indexTypes = singleIndexTypeBuf;
44604460
}
44614461

@@ -6192,13 +6192,14 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
61926192
// swap the order so that we load first and force the result.
61936193
cs.propagateLValueAccessKind(expr, AccessKind::Read);
61946194
if (auto *forceExpr = dyn_cast<ForceValueExpr>(expr)) {
6195-
fromType = forceExpr->getSubExpr()->getType()->getRValueType();
6195+
fromType = cs.getType(forceExpr->getSubExpr())->getRValueType();
61966196
auto *loadExpr = cs.cacheType(
61976197
new (tc.Context) LoadExpr(forceExpr->getSubExpr(), fromType));
61986198
auto *newForceValue = new (tc.Context)
61996199
ForceValueExpr(loadExpr, forceExpr->getLoc(),
62006200
forceExpr->isForceOfImplicitlyUnwrappedOptional());
6201-
cs.setType(newForceValue, loadExpr->getType()->getOptionalObjectType());
6201+
cs.setType(newForceValue,
6202+
cs.getType(loadExpr)->getOptionalObjectType());
62026203
expr = newForceValue;
62036204
} else {
62046205
expr = cs.cacheType(new (tc.Context)
@@ -7542,6 +7543,7 @@ namespace {
75427543
} else {
75437544
// For other closures, type-check the body once we've finished with
75447545
// the expression.
7546+
cs.setExprTypes(closure);
75457547
ClosuresToTypeCheck.push_back(closure);
75467548
}
75477549

lib/Sema/CSDiag.cpp

Lines changed: 2 additions & 0 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
}

lib/Sema/CSGen.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3451,6 +3451,7 @@ bool swift::typeCheckUnresolvedExpr(DeclContext &DC,
34513451
SmallVectorImpl<Type> &PossibleTypes) {
34523452
PrettyStackTraceExpr stackTrace(DC.getASTContext(),
34533453
"type-checking unresolved member", Parent);
3454+
34543455
ConstraintSystemOptions Options = ConstraintSystemFlags::AllowFixes;
34553456
auto *TC = static_cast<TypeChecker*>(DC.getASTContext().getLazyResolver());
34563457
ConstraintSystem CS(*TC, &DC, Options);
@@ -3468,7 +3469,7 @@ bool swift::typeCheckUnresolvedExpr(DeclContext &DC,
34683469
}
34693470

34703471
SmallVector<Solution, 3> solutions;
3471-
if (CS.solve(Parent, solutions, FreeTypeVariableBinding::Allow)) {
3472+
if (CS.solve(Parent, solutions, FreeTypeVariableBinding::UnresolvedType)) {
34723473
return false;
34733474
}
34743475

lib/Sema/ConstraintSystem.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,8 +1302,8 @@ class ConstraintSystem {
13021302
if (ExcludeRoot && expr == RootExpr)
13031303
return expr;
13041304

1305-
assert((!expr->getType() || CS.getType(expr)->isEqual(expr->getType()))
1306-
&& "Mismatched types!");
1305+
//assert((!expr->getType() || CS.getType(expr)->isEqual(expr->getType()))
1306+
// && "Mismatched types!");
13071307
assert(!CS.getType(expr)->hasTypeVariable() &&
13081308
"Should not write type variable into expression!");
13091309
expr->setType(CS.getType(expr));
@@ -1593,10 +1593,6 @@ class ConstraintSystem {
15931593
// "Expected type to be invariant!");
15941594

15951595
ExprTypes[E] = T.getPointer();
1596-
1597-
// FIXME: Temporary until all references to expression types are
1598-
// updated.
1599-
E->setType(T);
16001596
}
16011597

16021598
/// Check to see if we have a type for an expression.

test/Compatibility/tuple_arguments_3.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ do {
5959
}
6060

6161
do {
62-
var a = 3 // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
63-
var b = 4 // expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
64-
var c = (3) // expected-warning {{variable 'c' was never mutated; consider changing to 'let' constant}}
65-
var d = (a, b) // expected-warning {{variable 'd' was never mutated; consider changing to 'let' constant}}
62+
var a = 3
63+
var b = 4
64+
var c = (3)
65+
var d = (a, b)
6666

6767
concrete(a)
6868
concrete((a))
@@ -566,9 +566,9 @@ do {
566566
}
567567

568568
do {
569-
var a = 3 // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
570-
var b = 4 // expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
571-
var c = (a, b) // expected-warning {{variable 'c' was never mutated; consider changing to 'let' constant}}
569+
var a = 3
570+
var b = 4
571+
var c = (a, b)
572572

573573
_ = InitTwo(a, b)
574574
_ = InitTwo((a, b)) // expected-error {{missing argument for parameter #2 in call}}
@@ -623,9 +623,9 @@ do {
623623

624624
do {
625625
// TODO: Restore regressed diagnostics rdar://problem/31724211
626-
var a = 3 // e/xpected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
627-
var b = 4 // e/xpected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
628-
var d = (a, b) // e/xpected-warning {{variable 'd' was never mutated; consider changing to 'let' constant}}
626+
var a = 3
627+
var b = 4
628+
var d = (a, b)
629629

630630
var s1 = SubscriptTwo()
631631
_ = s1[a, b]
@@ -1030,9 +1030,9 @@ do {
10301030
}
10311031

10321032
do {
1033-
var a = 3 // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
1034-
var b = 4 // expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
1035-
var c = (a, b) // expected-warning {{variable 'c' was never mutated; consider changing to 'let' constant}}
1033+
var a = 3
1034+
var b = 4
1035+
var c = (a, b)
10361036

10371037
// _ = GenericInit<(Int, Int)>(a, b) // Crashes in Swift 3
10381038
_ = GenericInit<(Int, Int)>((a, b)) // expected-error {{expression type 'GenericInit<(Int, Int)>' is ambiguous without more context}}
@@ -1114,9 +1114,9 @@ do {
11141114

11151115
do {
11161116
// TODO: Restore regressed diagnostics rdar://problem/31724211
1117-
var a = 3.0 // e/xpected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
1118-
var b = 4.0 // e/xpected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
1119-
var d = (a, b) // e/xpected-warning {{variable 'd' was never mutated; consider changing to 'let' constant}}
1117+
var a = 3.0
1118+
var b = 4.0
1119+
var d = (a, b)
11201120

11211121
var s1 = GenericSubscript<(Double, Double)>()
11221122
_ = s1[a, b]

test/Compatibility/tuple_arguments_4.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ do {
4242
}
4343

4444
do {
45-
var a = 3 // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
46-
var b = 4 // expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
47-
var c = (3) // expected-warning {{variable 'c' was never mutated; consider changing to 'let' constant}}
48-
var d = (a, b) // expected-warning {{variable 'd' was never mutated; consider changing to 'let' constant}}
45+
var a = 3
46+
var b = 4
47+
var c = (3)
48+
var d = (a, b)
4949

5050
concrete(a)
5151
concrete((a))
@@ -550,9 +550,9 @@ do {
550550
}
551551

552552
do {
553-
var a = 3 // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
554-
var b = 4 // expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
555-
var c = (a, b) // expected-warning {{variable 'c' was never mutated; consider changing to 'let' constant}}
553+
var a = 3
554+
var b = 4
555+
var c = (a, b)
556556

557557
_ = InitTwo(a, b)
558558
_ = InitTwo((a, b)) // expected-error {{missing argument for parameter #2 in call}}
@@ -1015,9 +1015,9 @@ do {
10151015
}
10161016

10171017
do {
1018-
var a = 3 // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}}
1019-
var b = 4 // expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
1020-
var c = (a, b) // expected-warning {{variable 'c' was never mutated; consider changing to 'let' constant}}
1018+
var a = 3
1019+
var b = 4
1020+
var c = (a, b)
10211021

10221022
_ = GenericInit<(Int, Int)>(a, b) // expected-error {{extra argument in call}}
10231023
_ = GenericInit<(Int, Int)>((a, b))

test/Constraints/trailing_closures_objc.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ func foo(options: [AVMediaSelectionOption]) {
1717
func rdar28004686(a: [IndexPath]) {
1818
_ = a.sorted { (lhs: NSIndexPath, rhs: NSIndexPath) -> Bool in true }
1919
// expected-error@-1 {{'NSIndexPath' is not convertible to 'IndexPath'}}
20-
// expected-error@-2 {{call can throw, but it is not marked with 'try' and the error is not handled}}
21-
// The second error is erroneous: rdar://36744895
2220
}
2321

2422
class Test: NSObject {

0 commit comments

Comments
 (0)