unnecessary-await-in-return
Same as unnecessary_await_in_return in Dart lints
- Group
- Style
- Path
lint/style/unnecessary-await-in-return- Default
- Off, opt in
- Origin
- Dart lints
- Rule
- 449 of 512
Avoid await on a returned Future the function's own Future already covers.
Returning a Future from an async function already completes the
function's result with it, so awaiting first adds nothing:
Future<int> load() async => await fetch(); // BAD
Future<int> load() async => fetch(); // GOOD
Reported for return await e; statements and => await e bodies (including
grouped expressions) of functions, methods, and closures returning Future<R>,
when e is a Future<A> with A provably assignable to R. Closures and
local functions infer their return type, flattening nested futures and
respecting a closure's contextual Future or FutureOr return type. Untyped top-level
declarations do not infer it.
Returns inside a try or finally block are exempt.
Invalid
import 'dart:async';
Future<int> fetch() async => 1;
Future<String> fetchName() async => 'name';
Future<int> arrow() async => await fetch();
Future<int> block() async {
return await fetch();
}
Future<Object> wider() async {
return await fetchName();
}
Future<dynamic> dynamicResult() async => await fetch();
class Repository {
Future<int> load() async {
return await fetch();
}
Future<int> get count async => await fetch();
}
void outer() {
Future<int> local() async {
return await fetch();
}
local();
}
Future<int> afterTry() async {
try {
print('x');
} finally {
print('y');
}
return await fetch();
}
void inferredClosures() {
final arrow = () async => await fetch();
final block = () async {
return await fetch();
};
arrow();
block();
}
Future<List<int>> fetchList() async => <int>[1];
Future<List<num>> covariantFuture() async => await fetchList();
Future<int> nestedClosureInTry() async {
try {
final callback = () async => await fetch();
return callback();
} catch (_) {
return 0;
}
}
Future<Never> neverCompletes() => Future<Never>.error('failure');
Future<int> awaitsNever() async => await neverCompletes();
class AuthResult {}
class AuthSuccess extends AuthResult {}
void registerAuth(Future<AuthResult> Function() callback) {}
void subtypeClosure(Future<AuthSuccess> result) {
registerAuth(() async => await result);
}
void registerPreparation(FutureOr<void> Function() callback) {}
void futureOrClosure(Future<int> result) {
registerPreparation(() async => await result);
} Future<int> arrow() async => await fetch();Future<int> block() async { return await fetch();Future<Object> wider() async { return await fetchName(); Future<dynamic> dynamicResult() async => await fetch(); Future<int> load() async { return await fetch(); Future<int> get count async => await fetch(); Future<int> local() async { return await fetch(); } return await fetch();void inferredClosures() { final arrow = () async => await fetch(); final block = () async { return await fetch();Future<List<int>> fetchList() async => <int>[1];Future<List<num>> covariantFuture() async => await fetchList(); try { final callback = () async => await fetch();Future<Never> neverCompletes() => Future<Never>.error('failure');Future<int> awaitsNever() async => await neverCompletes();void subtypeClosure(Future<AuthSuccess> result) { registerAuth(() async => await result);void futureOrClosure(Future<int> result) { registerPreparation(() async => await result);Valid
Future<int> fetch() async => 1;
Future<String> fetchName() async => 'name';
Future<int> noAwait() async => fetch();
Future<int> plainReturn() async {
return fetch();
}
Future<int> awaitInTry() async {
try {
return await fetch();
} catch (e) {
return 0;
}
}
Future<int> awaitInFinally() async {
try {
print('x');
} finally {
return await fetch();
}
}
Future<String> mismatch() async {
return '${await fetch()}';
}
Future<void> used() async {
final value = await fetch();
print(value);
}
Future<int> awaitsNonFuture() async {
return await 1;
}
Future<num> transformed() async {
return (await fetch()) + 1;
}
void inferredClosureInTry() {
final callback = () async {
try {
return await fetch();
} catch (_) {
return 0;
}
};
callback();
}
inferredFunction() async => await fetch();
class UntypedDeclarations {
method() async => await fetch();
get value async => await fetch();
}
Future legacy() async => 1;
void register(Future<int> Function() callback) {}
void typedClosure() {
register(() async => await legacy());
}
Future<Future<int>> nested() async => fetch();
void flattenedClosure() {
final callback = () async => await nested();
callback();
}Configure unnecessary-await-in-return
Set its severity in falcon.json. See the configuration guide.
{
"linter": {
"rules": {
"style": {
"unnecessary-await-in-return": "error"
}
}
}
}Or silence one occurrence with a suppression comment; the reason is required.
// falcon-ignore lint/style/unnecessary-await-in-return: <reason>More style rules
- unnecessary-brace-in-string-interps
unnecessary_brace_in_string_interpsrecommendedFlags
${x}string interpolations whose braces can be dropped. - unnecessary-breaks
unnecessary_breaksrecommendedFlags a trailing
breakin a switch case that already ends implicitly. - unnecessary-constructor-name
unnecessary_constructor_namerecommendedFlags a redundant
.newon constructor declarations and invocations. - unnecessary-final
unnecessary_finalDon't use
finalfor local variables and parameters. - unnecessary-late
unnecessary_laterecommendedFlags a redundant
latemodifier on an initialized static or top-level variable. - unnecessary-library-directive
unnecessary_library_directiverecommendedFlags a
librarydirective that has neither a doc comment nor annotations. - unnecessary-library-name
unnecessary_library_namerecommendedFlags a
librarydirective that carries an explicit name. - unnecessary-new
unnecessary_newrecommendedFlags an explicit
newkeyword in an instance-creation expression.