Skip to content

Commit 93a8675

Browse files
authored
Merge pull request #76946 from pwongxy/diag-warn-on-for-var-loop
[Diagnostics] Improve warning suggestion for `var` in for loop
2 parents 02b4bac + c1473e8 commit 93a8675

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7100,6 +7100,10 @@ WARNING(variable_never_mutated, none,
71007100
"variable %0 was never mutated; "
71017101
"consider %select{removing 'var' to make it|changing to 'let'}1 constant",
71027102
(Identifier, bool))
7103+
WARNING(variable_tuple_elt_never_mutated, none,
7104+
"variable %0 was never mutated; "
7105+
"consider changing the pattern to 'case (..., let %1, ...)'",
7106+
(Identifier, StringRef))
71037107
WARNING(variable_never_read, none,
71047108
"variable %0 was written to, but never read",
71057109
(Identifier))

lib/Sema/MiscDiagnostics.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4122,8 +4122,20 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
41224122

41234123
// If this is a parameter explicitly marked 'var', remove it.
41244124
if (FixItLoc.isInvalid()) {
4125-
Diags.diagnose(var->getLoc(), diag::variable_never_mutated,
4126-
var->getName(), true);
4125+
bool suggestCaseLet = false;
4126+
if (auto *stmt = var->getRecursiveParentPatternStmt()) {
4127+
// Suggest 'var' -> 'case let' conversion
4128+
// in case of 'for' loop and invalid because it's
4129+
// tuple variable.
4130+
suggestCaseLet = isa<ForEachStmt>(stmt);
4131+
}
4132+
if (suggestCaseLet)
4133+
Diags.diagnose(var->getLoc(), diag::variable_tuple_elt_never_mutated,
4134+
var->getName(), var->getNameStr());
4135+
else
4136+
Diags.diagnose(var->getLoc(), diag::variable_never_mutated,
4137+
var->getName(), true);
4138+
41274139
}
41284140
else {
41294141
bool suggestLet = true;

test/decl/var/usage.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,3 +563,11 @@ func testUselessCastWithInvalidParam(foo: Any?) -> Int {
563563
if let bar = foo as? Foo { return 42 } // expected-warning {{value 'bar' was defined but never used; consider replacing with boolean test}} {{6-16=}} {{20-23=is}}
564564
else { return 54 }
565565
}
566+
567+
// https://github.com/swiftlang/swift/issues/72811
568+
func testEnumeratedForLoop(a: [Int]) {
569+
for var (b, c) in a.enumerated() { // expected-warning {{variable 'b' was never mutated; consider changing the pattern to 'case (..., let b, ...)'}}
570+
c = b
571+
let _ = c
572+
}
573+
}

0 commit comments

Comments
 (0)