avoid-contradictory-expressions

Path
lint/correctness/avoid-contradictory-expressions
Default
On (recommended)
Origin
Falcon
Rule
41 of 512
recommended

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

example.dartdart
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) {}
}
These conditions are always false together. Correct the contradictory comparison.
1void conditions(bool ready, int count, int other, String name) {
2 if (ready && !ready) {}
These conditions are always true together. Correct the contradictory comparison.
2 if (ready && !ready) {}
3 if (!ready || ready) {}
These conditions are always false together. Correct the contradictory comparison.
3 if (!ready || ready) {}
4 if ((ready) && !(ready)) {}
These conditions are always false together. Correct the contradictory comparison.
4 if ((ready) && !(ready)) {}
5 if (count == 2 && count != 2) {}
These conditions are always false together. Correct the contradictory comparison.
5 if (count == 2 && count != 2) {}
6 if (count == other && other != count) {}
These conditions are always true together. Correct the contradictory comparison.
6 if (count == other && other != count) {}
7 if (name == 'Ada' || 'Ada' != name) {}
These conditions are always false together. Correct the contradictory comparison.
7 if (name == 'Ada' || 'Ada' != name) {}
8 if (count == 3 && count == 4) {}
These conditions are always false together. Correct the contradictory comparison.
8 if (count == 3 && count == 4) {}
9 if (count < 4 && count > 4) {}
These conditions are always false together. Correct the contradictory comparison.
9 if (count < 4 && count > 4) {}
10 if (count >= 4 && count < 4) {}
These conditions are always false together. Correct the contradictory comparison.
10 if (count >= 4 && count < 4) {}
11 if (count > 3 && count < 4) {}
These conditions are always false together. Correct the contradictory comparison.
11 if (count > 3 && count < 4) {}
12 if (count <= -2 && count > -1) {}
These conditions are always false together. Correct the contradictory comparison.
12 if (count <= -2 && count > -1) {}
13 if (4 < count && count <= 4) {}
These conditions are always true together. Correct the contradictory comparison.
13 if (4 < count && count <= 4) {}
14 if (count <= 4 || count >= 5) {}
These conditions are always true together. Correct the contradictory comparison.
14 if (count <= 4 || count >= 5) {}
15 if (count != 1 || count != 2) {}
These conditions are always false together. Correct the contradictory comparison.
15 if (count != 1 || count != 2) {}
16 if (count == 4 && count > 4) {}
These conditions are always false together. Correct the contradictory comparison.
16 if (count == 4 && count > 4) {}
17 if (count >= 9007199254740993 && count < 9007199254740993) {}

Valid

example.dartdart
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.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-contradictory-expressions": "error"
      }
    }
  }
}

Or silence one occurrence with a suppression comment; the reason is required.

example.dartdart
// falcon-ignore lint/correctness/avoid-contradictory-expressions: <reason>