avoid-unnecessary-futures

Path
lint/performance/avoid-unnecessary-futures
Default
Off, opt in
Origin
Falcon
Rule
161 of 512

Prefer synchronous declarations when an async Future only returns scalars.

Only explicitly typed SDK Future top-level/local functions with known scalar returns are reported. Methods/getters are excluded to preserve inherited contracts. Awaiting, throwing, calls, accesses, operators and patterns exclude the body. No automatic fix is offered: changing a public return type requires callers to be updated as well.

Invalid

example.dartdart
import 'dart:async';
import 'dart:async' as async;

Future<int> immediate() async => 1;
Future<String> text() async => 'value';
async.Future<bool> flag() async => true;
Future<double> number() async {
  return 1.5;
}
Future<int> parameter(int value) async => value;
Future<int> local() async {
  final value = 1;
  return value;
}
This `async` declaration only returns immediate values. Make it synchronous and return the value type instead of `Future`, updating its callers.
3
4Future<int> immediate() async => 1;
This `async` declaration only returns immediate values. Make it synchronous and return the value type instead of `Future`, updating its callers.
4Future<int> immediate() async => 1;
5Future<String> text() async => 'value';
This `async` declaration only returns immediate values. Make it synchronous and return the value type instead of `Future`, updating its callers.
5Future<String> text() async => 'value';
6async.Future<bool> flag() async => true;
This `async` declaration only returns immediate values. Make it synchronous and return the value type instead of `Future`, updating its callers.
6async.Future<bool> flag() async => true;
7Future<double> number() async {
This `async` declaration only returns immediate values. Make it synchronous and return the value type instead of `Future`, updating its callers.
9}
10Future<int> parameter(int value) async => value;
This `async` declaration only returns immediate values. Make it synchronous and return the value type instead of `Future`, updating its callers.
10Future<int> parameter(int value) async => value;
11Future<int> local() async {

Valid

example.dartdart
import 'dart:async';
Future<int> forwarding() => Future<int>.value(1);
Future<int> awaited() async => await Future<int>.value(1);
Future<int> flatten(Future<int> value) async => value;
Future<int> union(FutureOr<int> value) async => value;
Future<dynamic> unknown(dynamic value) async => value;
Future<int> throwing() async { throw StateError('failed'); }
Future<int> canThrow() async => int.parse('1');
Future<int> asserts(int? value) async => value!;
Future<int> effects() async { print('effect'); return 1; }
Future<void> main() async {}
abstract class Contract { Future<int> value(); }
class Implementation implements Contract {
  @override
  Future<int> value() async => 1;
}
class Member {
  Future<int> value() async => 1;
}
Future<void> empty() async {}
Stream<int> generator() async* { yield 1; }
void callback() {
  final action = () async => 1;
  print(action);
}
int get dangerous => throw StateError('failed');
Future<int> getter() async => dangerous;
Future<int> interpolation(Object value) async {
  final text = '$value';
  return 1;
}
Future<int> iteration(Stream<int> values) async {
  await for (final value in values) {}
  return 1;
}
Future<int> destructureList(List<int> values) async {
  final [value] = values;
  return value;
}
class ThrowingGetter {
  int get value => throw StateError('failed');
}
Future<int> destructureObject(ThrowingGetter object) async {
  final ThrowingGetter(:value) = object;
  return value;
}

Configure avoid-unnecessary-futures

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

falcon.jsonjson
{
  "linter": {
    "rules": {
      "performance": {
        "avoid-unnecessary-futures": "error"
      }
    }
  }
}

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

example.dartdart
// falcon-ignore lint/performance/avoid-unnecessary-futures: <reason>