avoid-contradictory-expressions
- Group
- Correctness
- Path
lint/correctness/avoid-contradictory-expressions- Default
- On (recommended)
- Origin
- Falcon
- Rule
- 41 of 512
Flags pairs of conditions that are always false with && or true with ||.
Checks a stable boolean against its negation, complementary primitive equality comparisons, and incompatible integer comparisons against integer literals. Only directly paired conditions (allowing parentheses) are compared. Reads must be local variables or parameters; getters, fields, calls, dynamic values, and user-defined operators are excluded. Integer bounds use exact arithmetic; floating-point bounds are excluded because NaN invalidates total ordering.
Invalid
void conditions(bool ready, int count, int other, String name) {
if (ready && !ready) {}
if (!ready || ready) {}
if ((ready) && !(ready)) {}
if (count == 2 && count != 2) {}
if (count == other && other != count) {}
if (name == 'Ada' || 'Ada' != name) {}
if (count == 3 && count == 4) {}
if (count < 4 && count > 4) {}
if (count >= 4 && count < 4) {}
if (count > 3 && count < 4) {}
if (count <= -2 && count > -1) {}
if (4 < count && count <= 4) {}
if (count <= 4 || count >= 5) {}
if (count != 1 || count != 2) {}
if (count == 4 && count > 4) {}
if (count >= 9007199254740993 && count < 9007199254740993) {}
}void conditions(bool ready, int count, int other, String name) { if (ready && !ready) {} if (ready && !ready) {} if (!ready || ready) {} if (!ready || ready) {} if ((ready) && !(ready)) {} if ((ready) && !(ready)) {} if (count == 2 && count != 2) {} if (count == 2 && count != 2) {} if (count == other && other != count) {} if (count == other && other != count) {} if (name == 'Ada' || 'Ada' != name) {} if (name == 'Ada' || 'Ada' != name) {} if (count == 3 && count == 4) {} if (count == 3 && count == 4) {} if (count < 4 && count > 4) {} if (count < 4 && count > 4) {} if (count >= 4 && count < 4) {} if (count >= 4 && count < 4) {} if (count > 3 && count < 4) {} if (count > 3 && count < 4) {} if (count <= -2 && count > -1) {} if (count <= -2 && count > -1) {} if (4 < count && count <= 4) {} if (4 < count && count <= 4) {} if (count <= 4 || count >= 5) {} if (count <= 4 || count >= 5) {} if (count != 1 || count != 2) {} if (count != 1 || count != 2) {} if (count == 4 && count > 4) {} if (count == 4 && count > 4) {} if (count >= 9007199254740993 && count < 9007199254740993) {}Valid
void conditions(bool ready, bool other, int count, int limit, double floating,
dynamic unknown, String name) {
if (ready && !other) {}
if (count == 3 || count == 4) {}
if (count < 4 && count > 2) {}
if (count <= 4 && count >= 4) {}
if (count < 4 || count > 4) {}
if (count >= 3 && count != 3) {}
if (count < 4 && limit > 4) {}
if (name == 'a b' && name != 'ab') {}
// NaN makes both sides false, so this is not a tautology.
if (floating < 4 || floating >= 4) {}
if (unknown == 3 && unknown == 4) {}
if (next() && !next()) {}
if (changing && !changing) {}
if (nextNumber() == 3 && nextNumber() != 3) {}
}
bool next() => DateTime.now().millisecondsSinceEpoch.isEven;
int nextNumber() => DateTime.now().millisecondsSinceEpoch;
bool get changing => next();
class Custom {
bool operator <(int other) => next();
bool operator >(int other) => next();
@override
bool operator ==(Object other) => next();
@override
int get hashCode => 0;
}
void overloaded(Custom value) {
if (value < 4 && value > 4) {}
if (value == 3 && value != 3) {}
}
class Source {
bool get ready => next();
int get count => nextNumber();
void reads() {
if (ready && !ready) {}
if (count == 3 && count != 3) {}
}
}
class StoredValues {
final bool ready = true;
final int count = 0;
void reads() {
if (ready && !ready) {}
if (count == 3 && count != 3) {}
if (count > 4 && count < 4) {}
}
}
class ChangingValues extends StoredValues {
@override
bool get ready => next();
@override
int get count => nextNumber();
}
bool globalReady = true;
int globalCount = 0;
void globals() {
if (globalReady && !globalReady) {}
if (globalCount > 4 && globalCount < 4) {}
}Configure avoid-contradictory-expressions
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"correctness": {
"avoid-contradictory-expressions": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/correctness/avoid-contradictory-expressions: <reason>More correctness rules
- avoid-disposing-late-fieldsflutter
Avoid releasing late State fields that may be unset or initialized only by cleanup.
- avoid-duplicate-bloc-event-handlersrecommendedbloc
Flags later registrations of the same event type in a Bloc constructor.
- avoid-duplicate-cascades
Flags repeated field or index assignment targets within one cascade.
- avoid-duplicate-collection-elements
Flags repeated scalar literals and stable local reads in list and set literals.
- avoid-duplicate-exports
Flags export directives whose visible names are already covered by another export.
- avoid-duplicate-factories
Flags factories in one type with the same implementation, ignoring factory names and alpha-renaming parameters by position.
- avoid-duplicate-initializers
Flags final/const variables with identical initializers in the same scope.
- avoid-duplicate-map-keysrecommended
Flags repeated literal keys in map literals, including literal spreads and collection
ifentries.