Skip to content

Commit 595b198

Browse files
committed
[Diagnostics] Diagnose passing r-value without & to inout parameter as mutability problem
If argument is immutable, with or without explicit `&`, let's diagnose that as mutability problem because suggesting to add `&` to immutable declaration is not the best possible fix. Resolves: rdar://problem/62428353
1 parent 20e973d commit 595b198

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3040,9 +3040,15 @@ bool ConstraintSystem::repairFailures(
30403040
// position (which doesn't require explicit `&`) decays into
30413041
// a `Bind` of involved object types, same goes for explicit
30423042
// `&` conversion from l-value to inout type.
3043+
//
3044+
// In case of regular argument conversion although explicit `&`
3045+
// is required we still want to diagnose the problem as one
3046+
// about mutability instead of suggesting to add `&` which wouldn't
3047+
// be correct.
30433048
auto kind = (isExpr<InOutExpr>(anchor) ||
30443049
(rhs->is<InOutType>() &&
3045-
matchKind == ConstraintKind::OperatorArgumentConversion))
3050+
(matchKind == ConstraintKind::ArgumentConversion ||
3051+
matchKind == ConstraintKind::OperatorArgumentConversion)))
30463052
? ConstraintKind::Bind
30473053
: matchKind;
30483054

test/Constraints/diagnostics.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,3 +1477,9 @@ func generic<T>(_ value: inout T, _ closure: (SR12725<T>) -> Void) {}
14771477

14781478
let arg: Int
14791479
generic(&arg) { (g: SR12725<Double>) -> Void in } // expected-error {{cannot convert value of type '(SR12725<Double>) -> Void' to expected argument type '(SR12725<Int>) -> Void'}}
1480+
1481+
// rdar://problem/62428353 - bad error message for passing `T` where `inout T` was expected
1482+
func rdar62428353<T>(_ t: inout T) {
1483+
let v = t // expected-note {{change 'let' to 'var' to make it mutable}} {{3-6=var}}
1484+
rdar62428353(v) // expected-error {{cannot pass immutable value as inout argument: 'v' is a 'let' constant}}
1485+
}

0 commit comments

Comments
 (0)