Skip to content

Commit 3d85b80

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 (cherry picked from commit 595b198)
1 parent 77da956 commit 3d85b80

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
@@ -3111,9 +3111,15 @@ bool ConstraintSystem::repairFailures(
31113111
// position (which doesn't require explicit `&`) decays into
31123112
// a `Bind` of involved object types, same goes for explicit
31133113
// `&` conversion from l-value to inout type.
3114+
//
3115+
// In case of regular argument conversion although explicit `&`
3116+
// is required we still want to diagnose the problem as one
3117+
// about mutability instead of suggesting to add `&` which wouldn't
3118+
// be correct.
31143119
auto kind = (isa<InOutExpr>(anchor) ||
31153120
(rhs->is<InOutType>() &&
3116-
matchKind == ConstraintKind::OperatorArgumentConversion))
3121+
(matchKind == ConstraintKind::ArgumentConversion ||
3122+
matchKind == ConstraintKind::OperatorArgumentConversion)))
31173123
? ConstraintKind::Bind
31183124
: matchKind;
31193125

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)