function-always-returns-same-value

Path
lint/correctness/function-always-returns-same-value
Default
Off, opt in
Origin
Falcon
Rule
240 of 512

Warns when distinct return paths in a function produce the same scalar constant. Only synchronous value functions and scalar constants are considered. Unsupported control flow (including loops, switches and exception handling) fails closed.

Invalid

example.dartdart
const answer = 6 * 7;
int both(bool flag) {
  if (flag) { return 2 + 2; } else { return 4; }
}
String trailing(bool flag) {
  if (flag) return 'same';
  return "same";
}
int lexical(bool flag) {
  if (flag) return answer;
  return 42;
}
int nested(bool flag) {
  Object? inner() => null;
  if (flag) { if (flag) return 4; else return 4; }
  return 4;
}
class Example {
  int method(bool flag) {
    if (flag) return 42;
    return 42;
  }
}

bool constListEquality(bool flag) {
  if (flag) return const <int>[] == const <int>[];
  return true;
}
class ConstWrapper {
  final List<int> values;
  const ConstWrapper(this.values);
}
bool implicitConstContents(bool flag) {
  if (flag) return const ConstWrapper([]) == const ConstWrapper([]);
  return true;
}
This function returns the same constant on every path; simplify the function or return a meaningful result.
1const answer = 6 * 7;
2int both(bool flag) {
This function returns the same constant on every path; simplify the function or return a meaningful result.
4}
5String trailing(bool flag) {
This function returns the same constant on every path; simplify the function or return a meaningful result.
8}
9int lexical(bool flag) {
This function returns the same constant on every path; simplify the function or return a meaningful result.
12}
13int nested(bool flag) {
This function returns the same constant on every path; simplify the function or return a meaningful result.
18class Example {
19 int method(bool flag) {
This function returns the same constant on every path; simplify the function or return a meaningful result.
24
25bool constListEquality(bool flag) {
This function returns the same constant on every path; simplify the function or return a meaningful result.
32}
33bool implicitConstContents(bool flag) {

Valid

example.dartdart
int mixed(bool flag) { if (flag) return 1; return 2; }
int? fallthrough(bool flag) { if (flag) return 1; }
Object? empty() {}
Object? nullOnly() => null;
int variable(int value) => value;
const answer = 42;
int shadow(int answer) => answer;
int nested(int value) {
  Object? inner() => null;
  return value;
}
int finallyWins() { try { return 1; } finally { return 2; } }
int loop(bool flag) { while (flag) { return 1; } return 1; }
List<int> allocated() => [1, 2];
List<int> allocatedBranches(bool flag) { if (flag) return [1]; return [1]; }
Iterable<int> generator() sync* { yield 1; }
Future<int> asynchronous() async => 1;
int get answerGetter => 42;
class Example { int get value => 42; }

int arrow() => 42;
bool direct() { return true; }
typedef VoidCallback = void Function();
void onPressed(VoidCallback callback) {}
void useEffect(Object? Function() callback) {}
void callbacks() {
  VoidCallback callback = () => true;
  onPressed(() { return true; });
  useEffect(() { return true; });
  callback();
}
abstract class Contract {
  int result(bool flag);
  int get value;
}
class Implementation implements Contract {
  @override
  int result(bool flag) { if (flag) return 42; return 42; }
  @override
  int get value => 42;
}
bool differentEnvironmentFlags(bool branch) {
  if (branch) return const bool.fromEnvironment('FIRST');
  return const bool.fromEnvironment('SECOND');
}
const environmentFlag = bool.fromEnvironment('FIRST');
const wrappedFlag = !environmentFlag;
bool transitiveEnvironment(bool branch) {
  if (branch) return wrappedFlag;
  return true;
}
bool capturedEnvironment(bool branch) {
  const first = bool.fromEnvironment('FIRST');
  const second = bool.fromEnvironment('SECOND');
  if (branch) return first;
  return second;
}

const shadowedResult = 42;
class OwnGetterShadow {
  int current = 0;
  int get shadowedResult => current;
  int result(bool flag) {
    if (flag) return shadowedResult;
    return 42;
  }
}
class GetterBase {
  int current = 0;
  int get shadowedResult => current;
}
class InheritedGetterShadow extends GetterBase {
  int result(bool flag) {
    if (flag) return shadowedResult;
    return 42;
  }
}

extension NamedGetterShadow on String {
  int get shadowedResult => length;
  int namedResult(bool flag) {
    if (flag) return shadowedResult;
    return 42;
  }
}
extension on List<int> {
  int get shadowedResult => length;
  int unnamedResult(bool flag) {
    if (flag) return shadowedResult;
    return 42;
  }
}

bool freshListEquality(bool flag) {
  if (flag) return <int>[] == <int>[];
  return true;
}
bool freshSetEquality(bool flag) {
  if (flag) return <int>{} != <int>{};
  return false;
}
bool freshMapIdentity(bool flag) {
  if (flag) return identical(<int, int>{}, <int, int>{});
  return true;
}
class FreshValue { const FreshValue(); }
bool freshConstructorEquality(bool flag) {
  if (flag) return FreshValue() == FreshValue();
  return true;
}
bool nestedRecordIdentity(bool flag) {
  if (flag) return identical((<int>[],), (<int>[],));
  return true;
}
bool nestedRecordEquality(bool flag) {
  if (flag) return (<int>[],) == (<int>[],);
  return true;
}

Configure function-always-returns-same-value

Set its severity in falcon.json. See the configuration guide.

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "function-always-returns-same-value": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/correctness/function-always-returns-same-value: <reason>