Skip to content

Commit 465e5da

Browse files
committed
[Constraint system] Set the contextual type for condition expressions.
Set the contextual type of conditional expressions (to Bool) with the "condition" purpose so we get customized diagnostics for mistakes such as if x.property = y { } Prior to this, we'd get generic "() isn't convertible to Bool" diagnostic. Now we get use of '=' in a boolean context, did you mean '=='?
1 parent 27cd8d2 commit 465e5da

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

lib/Sema/CSGen.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3821,6 +3821,7 @@ bool ConstraintSystem::generateConstraints(StmtCondition condition,
38213821
return true;
38223822
}
38233823

3824+
Type boolTy = boolDecl->getDeclaredType();
38243825
for (const auto &condElement : condition) {
38253826
switch (condElement.getKind()) {
38263827
case StmtConditionElement::CK_Availability:
@@ -3829,15 +3830,18 @@ bool ConstraintSystem::generateConstraints(StmtCondition condition,
38293830

38303831
case StmtConditionElement::CK_Boolean: {
38313832
Expr *condExpr = condElement.getBoolean();
3833+
setContextualType(condExpr, TypeLoc::withoutLoc(boolTy), CTP_Condition);
3834+
38323835
condExpr = generateConstraints(condExpr, dc);
38333836
if (!condExpr) {
38343837
return true;
38353838
}
38363839

38373840
addConstraint(ConstraintKind::Conversion,
38383841
getType(condExpr),
3839-
boolDecl->getDeclaredType(),
3840-
getConstraintLocator(condExpr));
3842+
boolTy,
3843+
getConstraintLocator(condExpr,
3844+
LocatorPathElt::ContextualType()));
38413845
continue;
38423846
}
38433847

test/Constraints/function_builder_diags.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ struct MyTuplifiedStruct {
257257
}
258258
}
259259

260-
// Check that we're performing syntactic use diagnostics/
260+
// Check that we're performing syntactic use diagnostics.
261261
func acceptMetatype<T>(_: T.Type) -> Bool { true }
262262

263263
func syntacticUses<T>(_: T) {
@@ -269,3 +269,18 @@ func syntacticUses<T>(_: T) {
269269
}
270270
}
271271
}
272+
273+
// Check custom diagnostics within "if" conditions.
274+
struct HasProperty {
275+
var property: Bool = false
276+
}
277+
278+
func checkConditions(cond: Bool) {
279+
var x = HasProperty()
280+
281+
tuplify(cond) { value in
282+
if x.property = value { // expected-error{{use of '=' in a boolean context, did you mean '=='?}}
283+
"matched it"
284+
}
285+
}
286+
}

0 commit comments

Comments
 (0)