avoid_unnecessary_negations
v0.8.0 Warning Fix Control Flow
This rule flags a negation that can be removed without changing the meaning — !!flag, !(a != b), !true, and !a == !b.
Why use this rule
Section titled “Why use this rule”A double negation states a positive condition the long way. The reader has to unwind both operators before knowing what is actually being tested, and it is easy to miscount when the expression is longer.
Negating a boolean literal (!true) is just the other literal written indirectly. Negating both sides of an equality (!a == !b) cancels out entirely — the comparison gives the same answer without either !.
These usually appear when a condition is inverted during a change and the inner expression is left as it was.
if (!!isEnabled) { start();}
if (!(status != Status.active)) { activate();}
if (!true) { unreachable();}
if (!isReady == !isLoaded) { sync();}if (isEnabled) { start();}
if (status == Status.active) { activate();}
if (false) { unreachable();}
if (isReady == isLoaded) { sync();}Known limitations
Section titled “Known limitations”Four shapes are reported: ! applied to a ! expression, ! applied to a != comparison, ! applied to a boolean literal, and ==/!= with a negation on both sides. Parentheses are unwrapped first, so !(!flag) is caught.
A single negation in a comparison (!a == b) is left alone — removing it would change the result. A negated == (!(a == b)) is also deliberately excluded: it is a single negation, and rewriting it to != is a style preference rather than a redundancy. Negated relational comparisons are handled by avoid_inverted_boolean_checks instead, so the same code is never reported twice.
Configuration
Section titled “Configuration”This rule is in the core preset, so it is on with preset: core,
preset: recommended or preset: opinionated.
To turn it off:
rules: avoid_unnecessary_negations: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_inverted_boolean_checks— Use the opposite operator instead of negating a comparison.avoid_negated_conditions— State the positive case first in an if/else.prefer_returning_condition— Return the condition instead of true/false branches.avoid_cascade_after_if_null— Detect cascades after if-null operators without parentheses.