Created separated warning group for warnings about unnecessary mutable weak variables

This commit is contained in:
Mykola Pokhylets
2025-07-09 19:57:56 +02:00
parent 89f8f8b9bf
commit 86100fe685
5 changed files with 23 additions and 6 deletions

View File

@@ -72,6 +72,7 @@ GROUP(TemporaryPointers, "temporary-pointers")
GROUP(TrailingClosureMatching, "trailing-closure-matching")
GROUP(UnknownWarningGroup, "unknown-warning-group")
GROUP(CompilationCaching, "compilation-caching")
GROUP(WeakMutability, "weak-mutability")
#define UNDEFINE_DIAGNOSTIC_GROUPS_MACROS
#include "swift/AST/DefineDiagnosticGroupsMacros.h"

View File

@@ -7414,6 +7414,14 @@ WARNING(variable_tuple_elt_never_mutated, none,
"variable %0 was never mutated; "
"consider changing the pattern to 'case (..., let %1, ...)'",
(Identifier, StringRef))
GROUPED_WARNING(weak_variable_never_mutated, WeakMutability, none,
"weak variable %0 was never mutated; "
"consider %select{removing 'var' to make it|changing to 'let'}1 constant",
(Identifier, bool))
GROUPED_WARNING(weak_variable_tuple_elt_never_mutated, WeakMutability, none,
"weak variable %0 was never mutated; "
"consider changing the pattern to 'case (..., let %1, ...)'",
(Identifier, StringRef))
WARNING(variable_never_read, none,
"variable %0 was written to, but never read",
(Identifier))

View File

@@ -4283,6 +4283,8 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
if (isUsedInInactive(var))
continue;
bool isWeak = var->getInterfaceType()->is<WeakStorageType>();
// If this is a parameter explicitly marked 'var', remove it.
if (FixItLoc.isInvalid()) {
bool suggestCaseLet = false;
@@ -4293,10 +4295,14 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
suggestCaseLet = isa<ForEachStmt>(stmt);
}
if (suggestCaseLet)
Diags.diagnose(var->getLoc(), diag::variable_tuple_elt_never_mutated,
Diags.diagnose(var->getLoc(),
isWeak ? diag::weak_variable_tuple_elt_never_mutated
: diag::variable_tuple_elt_never_mutated,
var->getName(), var->getNameStr());
else
Diags.diagnose(var->getLoc(), diag::variable_never_mutated,
Diags.diagnose(var->getLoc(),
isWeak ? diag::weak_variable_never_mutated
: diag::variable_never_mutated,
var->getName(), true);
}
@@ -4309,7 +4315,9 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
suggestLet = !isa<ForEachStmt>(stmt);
}
auto diag = Diags.diagnose(var->getLoc(), diag::variable_never_mutated,
auto diag = Diags.diagnose(var->getLoc(),
isWeak ? diag::weak_variable_never_mutated
: diag::variable_never_mutated,
var->getName(), suggestLet);
if (suggestLet)

View File

@@ -98,7 +98,7 @@ final class CheckSendability12: Sendable {
func checkWeakCapture1(_ strongRef: S) -> @Sendable () -> Void {
// expected-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
// expected-warning@+1 {{weak variable 'weakRef' was never mutated; consider changing to 'let' constant}}
weak var weakRef: S? = strongRef
return {
// expected-error@+1 {{reference to captured var 'weakRef' in concurrently-executing code}}
@@ -124,7 +124,7 @@ func checkWeakCapture3(_ strongRef: S) -> @Sendable () -> Void {
}
func checkWeakCapture4(_ strongRef: NS) -> @Sendable () -> Void {
// expected-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
// expected-warning@+1 {{weak variable 'weakRef' was never mutated; consider changing to 'let' constant}}
weak var weakRef: NS? = strongRef
return {
// expected-error@+2 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}

View File

@@ -103,7 +103,7 @@ func test2() {
// Weak
// expected-warning@+1 {{variable 'w1' was never mutated; consider changing to 'let' constant}} {{8-11=let}}
// expected-warning@+1 {{weak variable 'w1' was never mutated; consider changing to 'let' constant}} {{8-11=let}}
weak var w1 : SomeClass?
_ = w1 // ok: default-initialized