-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cfe] Disallow void in await expression
Closes #41602 Change-Id: I29b8880e3fdb769b2acdf2c82a9ced038d7b0d94 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149287 Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
- Loading branch information
1 parent
f90391a
commit 665c58a
Showing
16 changed files
with
475 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
Future<void> returnFutureOfVoid() async {} | ||
|
||
void returnVoid() {} | ||
|
||
void returnVoidAsync() async {} | ||
|
||
test() async { | ||
await returnVoid(); // error | ||
await returnVoidAsync(); // error | ||
} | ||
|
||
main() async { | ||
await returnFutureOfVoid(); // ok | ||
} |
14 changes: 14 additions & 0 deletions
14
pkg/front_end/testcases/nnbd/issue41602.dart.outline.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
library /*isNonNullableByDefault*/; | ||
import self as self; | ||
import "dart:async" as asy; | ||
|
||
static method returnFutureOfVoid() → asy::Future<void> | ||
; | ||
static method returnVoid() → void | ||
; | ||
static method returnVoidAsync() → void | ||
; | ||
static method test() → dynamic | ||
; | ||
static method main() → dynamic | ||
; |
25 changes: 25 additions & 0 deletions
25
pkg/front_end/testcases/nnbd/issue41602.dart.strong.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
library /*isNonNullableByDefault*/; | ||
// | ||
// Problems in library: | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:12:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoid(); // error | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:13:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoidAsync(); // error | ||
// ^ | ||
// | ||
import self as self; | ||
import "dart:async" as asy; | ||
|
||
static method returnFutureOfVoid() → asy::Future<void> async {} | ||
static method returnVoid() → void {} | ||
static method returnVoidAsync() → void async {} | ||
static method test() → dynamic async { | ||
await self::returnVoid(); | ||
await self::returnVoidAsync(); | ||
} | ||
static method main() → dynamic async { | ||
await self::returnFutureOfVoid(); | ||
} |
124 changes: 124 additions & 0 deletions
124
pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
library /*isNonNullableByDefault*/; | ||
// | ||
// Problems in library: | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:12:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoid(); // error | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:13:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoidAsync(); // error | ||
// ^ | ||
// | ||
import self as self; | ||
import "dart:async" as asy; | ||
import "dart:core" as core; | ||
import "dart:_internal" as _in; | ||
|
||
static method returnFutureOfVoid() → asy::Future<void> /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>(); | ||
asy::FutureOr<void>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L1: | ||
{} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} | ||
static method returnVoid() → void {} | ||
static method returnVoidAsync() → void /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); | ||
asy::FutureOr<dynamic>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L2: | ||
{} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} | ||
static method test() → dynamic /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); | ||
asy::FutureOr<dynamic>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
dynamic :saved_try_context_var0; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L3: | ||
{ | ||
[yield] let dynamic #t1 = asy::_awaitHelper(self::returnVoid(), :async_op_then, :async_op_error, :async_op) in null; | ||
_in::unsafeCast<void>(:result); | ||
[yield] let dynamic #t2 = asy::_awaitHelper(self::returnVoidAsync(), :async_op_then, :async_op_error, :async_op) in null; | ||
_in::unsafeCast<void>(:result); | ||
} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} | ||
static method main() → dynamic /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); | ||
asy::FutureOr<dynamic>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
dynamic :saved_try_context_var0; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L4: | ||
{ | ||
[yield] let dynamic #t3 = asy::_awaitHelper(self::returnFutureOfVoid(), :async_op_then, :async_op_error, :async_op) in null; | ||
_in::unsafeCast<void>(:result); | ||
} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} |
5 changes: 5 additions & 0 deletions
5
pkg/front_end/testcases/nnbd/issue41602.dart.textual_outline.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Future<void> returnFutureOfVoid() async {} | ||
void returnVoid() {} | ||
void returnVoidAsync() async {} | ||
test() async {} | ||
main() async {} |
5 changes: 5 additions & 0 deletions
5
pkg/front_end/testcases/nnbd/issue41602.dart.textual_outline_modelled.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Future<void> returnFutureOfVoid() async {} | ||
main() async {} | ||
test() async {} | ||
void returnVoid() {} | ||
void returnVoidAsync() async {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
library /*isNonNullableByDefault*/; | ||
// | ||
// Problems in library: | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:12:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoid(); // error | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:13:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoidAsync(); // error | ||
// ^ | ||
// | ||
import self as self; | ||
import "dart:async" as asy; | ||
|
||
static method returnFutureOfVoid() → asy::Future<void> async {} | ||
static method returnVoid() → void {} | ||
static method returnVoidAsync() → void async {} | ||
static method test() → dynamic async { | ||
await self::returnVoid(); | ||
await self::returnVoidAsync(); | ||
} | ||
static method main() → dynamic async { | ||
await self::returnFutureOfVoid(); | ||
} |
124 changes: 124 additions & 0 deletions
124
pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
library /*isNonNullableByDefault*/; | ||
// | ||
// Problems in library: | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:12:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoid(); // error | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/nnbd/issue41602.dart:13:9: Error: This expression has type 'void' and can't be used. | ||
// await returnVoidAsync(); // error | ||
// ^ | ||
// | ||
import self as self; | ||
import "dart:async" as asy; | ||
import "dart:core" as core; | ||
import "dart:_internal" as _in; | ||
|
||
static method returnFutureOfVoid() → asy::Future<void> /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>(); | ||
asy::FutureOr<void>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L1: | ||
{} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} | ||
static method returnVoid() → void {} | ||
static method returnVoidAsync() → void /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); | ||
asy::FutureOr<dynamic>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L2: | ||
{} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} | ||
static method test() → dynamic /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); | ||
asy::FutureOr<dynamic>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
dynamic :saved_try_context_var0; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L3: | ||
{ | ||
[yield] let dynamic #t1 = asy::_awaitHelper(self::returnVoid(), :async_op_then, :async_op_error, :async_op) in null; | ||
_in::unsafeCast<void>(:result); | ||
[yield] let dynamic #t2 = asy::_awaitHelper(self::returnVoidAsync(), :async_op_then, :async_op_error, :async_op) in null; | ||
_in::unsafeCast<void>(:result); | ||
} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} | ||
static method main() → dynamic /* originally async */ { | ||
final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>(); | ||
asy::FutureOr<dynamic>? :return_value; | ||
dynamic :async_stack_trace; | ||
(dynamic) → dynamic :async_op_then; | ||
(core::Object, core::StackTrace) → dynamic :async_op_error; | ||
core::int :await_jump_var = 0; | ||
dynamic :await_ctx_var; | ||
dynamic :saved_try_context_var0; | ||
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding | ||
try { | ||
#L4: | ||
{ | ||
[yield] let dynamic #t3 = asy::_awaitHelper(self::returnFutureOfVoid(), :async_op_then, :async_op_error, :async_op) in null; | ||
_in::unsafeCast<void>(:result); | ||
} | ||
asy::_completeOnAsyncReturn(:async_completer, :return_value); | ||
return; | ||
} | ||
on dynamic catch(dynamic exception, core::StackTrace stack_trace) { | ||
:async_completer.{asy::Completer::completeError}(exception, stack_trace); | ||
} | ||
:async_stack_trace = asy::_asyncStackTraceHelper(:async_op); | ||
:async_op_then = asy::_asyncThenWrapperHelper(:async_op); | ||
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op); | ||
:async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op); | ||
return :async_completer.{asy::Completer::future}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
// @dart=2.7 | ||
|
||
Future<void> returnFutureOfVoid() async {} | ||
|
||
void returnVoid() {} | ||
|
||
void returnVoidAsync() async {} | ||
|
||
main() async { | ||
await returnVoid(); // ok since this library is opted out. | ||
await returnFutureOfVoid(); // ok | ||
await returnVoidAsync(); // ok since this library is opted out. | ||
} |
5 changes: 5 additions & 0 deletions
5
pkg/front_end/testcases/nnbd_mixed/issue41602.dart.textual_outline.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// @dart = 2.7 | ||
Future<void> returnFutureOfVoid() async {} | ||
void returnVoid() {} | ||
void returnVoidAsync() async {} | ||
main() async {} |
5 changes: 5 additions & 0 deletions
5
pkg/front_end/testcases/nnbd_mixed/issue41602.dart.textual_outline_modelled.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// @dart = 2.7 | ||
Future<void> returnFutureOfVoid() async {} | ||
main() async {} | ||
void returnVoid() {} | ||
void returnVoidAsync() async {} |
Oops, something went wrong.