diff --git a/Language/Statements/Return/execution_A01_t04.dart b/Language/Statements/Return/execution_A01_t04.dart new file mode 100644 index 0000000000..4930900af7 --- /dev/null +++ b/Language/Statements/Return/execution_A01_t04.dart @@ -0,0 +1,54 @@ +// Copyright (c) 2026, 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. + +/// @assertion The execution of a return statement proceeds as follows. +/// +/// Case ⟨Synchronous non-generator functions and factory constructors⟩. Let `s` +/// be a statement of the form `return e;`. Let `f` be the immediately enclosing +/// function, and consider the case where `f` is a synchronous non-generator or +/// a factory constructor. Execution of `s` proceeds as follows. +/// +/// The expression `e` is evaluated to an object `o`. A dynamic error occurs +/// unless the dynamic type of `o` is a subtype of the actual return type of `f`. +/// Then the return statement `s` completes returning `o`. +/// +/// @description Checks that no error occurs if the run-time type of `e` is a +/// subtype of the actual return type of `f`. +/// @author sgrekhov22@gmail.com + +import 'dart:async'; +import '../../../Utils/expect.dart'; + +num f1() { + return 1 as dynamic; +} + +num f2() { + return 3.14 as dynamic; +} + +num? f3() { + return null as dynamic; +} + +FutureOr f4() { + return 4; +} + +FutureOr f5() { + return Future.value(5); +} + +int f6(v) { + return v; +} + +main() async { + Expect.equals(1, f1()); + Expect.equals(3.14, f2()); + Expect.isNull(f3()); + Expect.equals(4, f4()); + Expect.equals(5, await f5()); + Expect.equals(6, f6(6 as num)); +} diff --git a/Language/Statements/Return/execution_A01_t05.dart b/Language/Statements/Return/execution_A01_t05.dart new file mode 100644 index 0000000000..236ce5f910 --- /dev/null +++ b/Language/Statements/Return/execution_A01_t05.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2026, 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. + +/// @assertion The execution of a return statement proceeds as follows. +/// +/// Case ⟨Synchronous non-generator functions and factory constructors⟩. Let `s` +/// be a statement of the form `return e;`. Let `f` be the immediately enclosing +/// function, and consider the case where `f` is a synchronous non-generator or +/// a factory constructor. Execution of `s` proceeds as follows. +/// +/// The expression `e` is evaluated to an object `o`. A dynamic error occurs +/// unless the dynamic type of `o` is a subtype of the actual return type of `f`. +/// Then the return statement `s` completes returning `o`. +/// +/// @description Checks that it is dynamic error if the run-time type of `e` is +/// not a subtype of the actual return type of `f`. +/// @author sgrekhov22@gmail.com + +import 'dart:async'; +import '../../../Utils/expect.dart'; + +int foo(v) { + return v; +} + +main() async { + Expect.throws(() { + foo(3.14); + }); + Expect.throws(() { + foo(null); + }); +} diff --git a/Language/Statements/Return/execution_A02_t01.dart b/Language/Statements/Return/execution_A02_t01.dart new file mode 100644 index 0000000000..0d081fc26d --- /dev/null +++ b/Language/Statements/Return/execution_A02_t01.dart @@ -0,0 +1,60 @@ +// Copyright (c) 2026, 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. + +/// @assertion The execution of a return statement proceeds as follows. +/// ... +/// Case ⟨Asynchronous non-generator functions⟩. Let `s` be a statement of the +/// form return `e;`. Let `f` be the immediately enclosing function, and +/// consider the case where `f` is an asynchronous non-generator with future +/// value type `Tv`. +/// +/// Execution of `s` proceeds as follows. +/// +/// The expression `e` is evaluated to an object `o`. If the run-time type of +/// `o` is a subtype of `Future`, let `v` be a fresh variable bound to `o` +/// and evaluate `await v` to an object `r`; otherwise let `r` be `o`. A dynamic +/// error occurs unless the dynamic type of `r` is a subtype of the actual value +/// of `Tv`. Then the return statement `s` completes returning `r`. +/// +/// @description Checks that if the run-time type of `o` is a subtype of +/// `Future` then the result of `await v;` is returned. +/// @author sgrekhov22@gmail.com + +import 'dart:async'; +import '../../../Utils/expect.dart'; + +Future r(T v) async => v; + +Future foo() async { + return r(1); +} + +FutureOr bar() async { + return r(2); +} + +Future baz() async { + return 3; +} + +FutureOr qux() async { + return 4; +} + +FutureOr quux() async { + return r(5); +} + +main() async { + Expect.notEquals(await r(1), foo()); // The expected values are directly based on the specified behavior + Expect.equals(await r(1), await foo()); + Expect.notEquals(await r(2), bar()); + Expect.equals(await r(2), await bar()); + Expect.notEquals(3, baz()); + Expect.equals(3, await baz()); + Expect.notEquals(4, qux()); + Expect.equals(4, await qux()); + Expect.notEquals(await r(5), quux()); + Expect.equals(await r(5), await quux()); +} diff --git a/Language/Statements/Return/execution_A02_t02.dart b/Language/Statements/Return/execution_A02_t02.dart new file mode 100644 index 0000000000..6ee22f0ffe --- /dev/null +++ b/Language/Statements/Return/execution_A02_t02.dart @@ -0,0 +1,54 @@ +// Copyright (c) 2026, 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. + +/// @assertion The execution of a return statement proceeds as follows. +/// ... +/// Case ⟨Asynchronous non-generator functions⟩. Let `s` be a statement of the +/// form return `e;`. Let `f` be the immediately enclosing function, and +/// consider the case where `f` is an asynchronous non-generator with future +/// value type `Tv`. +/// +/// Execution of `s` proceeds as follows. +/// +/// The expression `e` is evaluated to an object `o`. If the run-time type of +/// `o` is a subtype of `Future`, let `v` be a fresh variable bound to `o` +/// and evaluate `await v` to an object `r`; otherwise let `r` be `o`. A dynamic +/// error occurs unless the dynamic type of `r` is a subtype of the actual value +/// of `Tv`. Then the return statement `s` completes returning `r`. +/// +/// @description Checks that if the run-time type of `o` is a not a subtype of +/// `Future` and not a subtype of `Tv` then dynamic error occurs. +/// @author sgrekhov22@gmail.com + +import '../../../Utils/expect.dart'; + +Future r(T r) async => r; + +Future foo() async { + return r(1) as dynamic; +} + +Future bar() async { + return 3.14 as dynamic; +} + +main() async { + var success = false; + asyncStart(2); + foo().then((_) { + success = true; + }).onError((_, _) { + asyncEnd(); + }).whenComplete(() { + Expect.isFalse(success); + }); + + bar().then((_) { + success = true; + }).onError((_, _) { + asyncEnd(); + }).whenComplete(() { + Expect.isFalse(success); + }); +} diff --git a/Language/Statements/Return/execution_A02_t03.dart b/Language/Statements/Return/execution_A02_t03.dart new file mode 100644 index 0000000000..ed72964336 --- /dev/null +++ b/Language/Statements/Return/execution_A02_t03.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2026, 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. + +/// @assertion The execution of a return statement proceeds as follows. +/// ... +/// Case ⟨Asynchronous non-generator functions⟩. Let `s` be a statement of the +/// form return `e;`. Let `f` be the immediately enclosing function, and +/// consider the case where `f` is an asynchronous non-generator with future +/// value type `Tv`. +/// +/// Execution of `s` proceeds as follows. +/// +/// The expression `e` is evaluated to an object `o`. If the run-time type of +/// `o` is a subtype of `Future`, let `v` be a fresh variable bound to `o` +/// and evaluate `await v` to an object `r`; otherwise let `r` be `o`. A dynamic +/// error occurs unless the dynamic type of `r` is a subtype of the actual value +/// of `Tv`. Then the return statement `s` completes returning `r`. +/// +/// @description Checks that if a return statement is executing in a try-finally +/// block then finally is also executed. +/// @author sgrekhov22@gmail.com + +import '../../../Utils/expect.dart'; + +Future foo() async { + try { + return 1; + } finally { + return 2; + } +} + +main() async { + Expect.equals(2, await foo()); +} diff --git a/Language/Statements/Return/execution_A02_t04.dart b/Language/Statements/Return/execution_A02_t04.dart new file mode 100644 index 0000000000..c11612ebc8 --- /dev/null +++ b/Language/Statements/Return/execution_A02_t04.dart @@ -0,0 +1,50 @@ +// Copyright (c) 2026, 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. + +/// @assertion The execution of a return statement proceeds as follows. +/// ... +/// Case ⟨Asynchronous non-generator functions⟩. Let `s` be a statement of the +/// form return `e;`. Let `f` be the immediately enclosing function, and +/// consider the case where `f` is an asynchronous non-generator with future +/// value type `Tv`. +/// +/// Execution of `s` proceeds as follows. +/// +/// The expression `e` is evaluated to an object `o`. If the run-time type of +/// `o` is a subtype of `Future`, let `v` be a fresh variable bound to `o` +/// and evaluate `await v` to an object `r`; otherwise let `r` be `o`. A dynamic +/// error occurs unless the dynamic type of `r` is a subtype of the actual value +/// of `Tv`. Then the return statement `s` completes returning `r`. +/// +/// @description Checks that if the run-time type of `o` is a not a subtype of +/// `Future` then dynamic error occurs. +/// @author sgrekhov22@gmail.com +/// @issue 44395 + +import '../../../Utils/expect.dart'; + +Future r(T r) async => r; + +Future foo() async { + try { + return r(1) as dynamic; + } on Error { + return 2; + } +} + +Future bar() async { + try { + return r(1) as dynamic; + } on Error { + return 2; + } finally { + return 3; + } +} + +main() async { + Expect.equals(2, await foo()); + Expect.equals(3, await bar()); +} diff --git a/Language/Statements/Return/execution_t01.dart b/Language/Statements/Return/execution_t01.dart index fcff307156..9b0974c9b4 100644 --- a/Language/Statements/Return/execution_t01.dart +++ b/Language/Statements/Return/execution_t01.dart @@ -2,21 +2,17 @@ // 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. -/// @assertion Executing a return statement `return e;` proceeds as follows: +/// @assertion The execution of a return statement proceeds as follows. +/// +/// Case ⟨Synchronous non-generator functions and factory constructors⟩. Let `s` +/// be a statement of the form `return e;`. Let `f` be the immediately enclosing +/// function, and consider the case where `f` is a synchronous non-generator or +/// a factory constructor. Execution of `s` proceeds as follows. /// -/// When `f` is a synchronous non-generator, evaluation proceeds as follows: /// The expression `e` is evaluated to an object `o`. A dynamic error occurs /// unless the dynamic type of `o` is a subtype of the actual return type of `f`. /// Then the return statement `s` completes returning `o`. /// -/// When `f` is an asynchronous non-generator with future value type `T`, -/// evaluation proceeds as follows: -/// The expression `e` is evaluated to an object `o`. If the run-time type of -/// `o` is a subtype of `Future`,let `v` be a fresh variable bound to `o` and -/// evaluate `await v` to an object `r`; otherwise let `r` be `o`. A dynamic -/// error occurs unless the dynamic type of `r` is a subtype of the actual value -/// of `T`. Then the return statement `s` completes returning `r`. -/// /// @description Checks that the return statement returns a value received after /// evaluating the return expression and if this evaluation results in a runtime /// exception the control is transferred to the appropriate handler. @@ -34,7 +30,7 @@ bar(x) { class A { run() { - throw 1; + return throw 1; } } diff --git a/Language/Statements/Return/execution_t02.dart b/Language/Statements/Return/execution_t02.dart index 80f7dae171..e01c812ed1 100644 --- a/Language/Statements/Return/execution_t02.dart +++ b/Language/Statements/Return/execution_t02.dart @@ -2,21 +2,17 @@ // 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. -/// @assertion Executing a return statement `return e;` proceeds as follows: +/// @assertion The execution of a return statement proceeds as follows. +/// +/// Case ⟨Synchronous non-generator functions and factory constructors⟩. Let `s` +/// be a statement of the form `return e;`. Let `f` be the immediately enclosing +/// function, and consider the case where `f` is a synchronous non-generator or +/// a factory constructor. Execution of `s` proceeds as follows. /// -/// When `f` is a synchronous non-generator, evaluation proceeds as follows: /// The expression `e` is evaluated to an object `o`. A dynamic error occurs /// unless the dynamic type of `o` is a subtype of the actual return type of `f`. /// Then the return statement `s` completes returning `o`. /// -/// When `f` is an asynchronous non-generator with future value type `T`, -/// evaluation proceeds as follows: -/// The expression `e` is evaluated to an object `o`. If the run-time type of -/// `o` is a subtype of `Future`,let `v` be a fresh variable bound to `o` and -/// evaluate `await v` to an object `r`; otherwise let `r` be `o`. A dynamic -/// error occurs unless the dynamic type of `r` is a subtype of the actual value -/// of `T`. Then the return statement `s` completes returning `r`. -/// /// @description Checks that a `finally` statement is executed if the control is /// transferred from a try block using a `return` statement. /// @author iefremov diff --git a/Language/Statements/Return/execution_t03.dart b/Language/Statements/Return/execution_t03.dart index f2216699d0..5b88627594 100644 --- a/Language/Statements/Return/execution_t03.dart +++ b/Language/Statements/Return/execution_t03.dart @@ -2,21 +2,17 @@ // 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. -/// @assertion Executing a return statement `return e;` proceeds as follows: +/// @assertion The execution of a return statement proceeds as follows. +/// +/// Case ⟨Synchronous non-generator functions and factory constructors⟩. Let `s` +/// be a statement of the form `return e;`. Let `f` be the immediately enclosing +/// function, and consider the case where `f` is a synchronous non-generator or +/// a factory constructor. Execution of `s` proceeds as follows. /// -/// When `f` is a synchronous non-generator, evaluation proceeds as follows: /// The expression `e` is evaluated to an object `o`. A dynamic error occurs /// unless the dynamic type of `o` is a subtype of the actual return type of `f`. /// Then the return statement `s` completes returning `o`. /// -/// When `f` is an asynchronous non-generator with future value type `T`, -/// evaluation proceeds as follows: -/// The expression `e` is evaluated to an object `o`. If the run-time type of -/// `o` is a subtype of `Future`,let `v` be a fresh variable bound to `o` and -/// evaluate `await v` to an object `r`; otherwise let `r` be `o`. A dynamic -/// error occurs unless the dynamic type of `r` is a subtype of the actual value -/// of `T`. Then the return statement `s` completes returning `r`. -/// /// @description Checks that a finally statement is executed if the control /// is transferred from a try block using a return statement. /// @author iefremov