dart-sdk/tests/dartdevc
Lasse R.H. Nielsen 69f32d6ad7 Refactor _Future.
This is a major rewrite of the `_Future` class,
which is the default implementation of the `Future` interface.

The main goal was to reduce the number of expensive type checks
in the internal passing around of data.
Expensive type checks are things like
* `is _Future<T>` (more expensive than just `is _Future`, the latter
  can be a single class-ID check.
* Covariant generic parameter checks (using `T` covariantly in a
  parameter forces a run-time type check).

Also removed some plain unnecessary casts and turned some
implicit casts from `dynamic` into `unsafeCast`s.

This seems to be an success, at least on very primitive benchmarks, according to Golem:
FutureCatchErrorTest    41.22% (1.9 noise)
FutureValueTest         46.51% (2.8 noise)
EmptyFutureTest         59.15% (3.1 noise)
FutureWhenCompleteTest  51.10% (3.2 noise)

A secondary goal was to clean up a very old and messy class,
and make it clearer for other `dart:async` how to interact
with the future.

The change has a memory cost: The `_FutureListener<S,T>` class,
which represents a `then`, `catchError` or `whenComplete`
call on a `_Future`, now contains a reference to its source future,
the one which provides the inputs to the callbacks,
as well as the result future returned by the call.
That's one extra memory slot per listener.

In return, the `_FutureListener` now does not need to
get its source future as an argument, which needs a covariant
generic type check, and the methods of `_Future` can be written
in a way which ignores the type parameters of both `_Future`
and `_FutureListener`, which reduces complex type checks
significantly.

In general, typed code is in `_FutureListener`, which knows both
the source and target types of the listener callbacks, and which
contains the futures already at that type, so no extra type checking
is needed.
The `_Future` class is mostly untyped, except for its "public"
API, called by other classes, which checks inputs,
and code interacting with non-native futures.
Invariants ensure that only correctly typed values
are stored in the untyped shared `_resultOrListeners` field
on `_Future`, as determined by its `_state` integer.
(This was already partially true, and has simply been made
more consistent.)

Further, we now throw an error in a situation that was previously
unhandled: When a `_Future` is completed with *itself*.
That would ensure that the future would never complete
(it waits for itself to complete before it can complete),
and may potentially have caused weird loops in the representation.
In practice, it probably never happens. Now it makes the error
fail with an error.
Currently a private `_FutureCyclicDependencyError` which presents
as an `UnsupportedError`.
That avoids code like
```dart
import "dart:async";
void main() {
  var c = Completer();
  c.complete(c.future); // bad.
  print("well!");
  var d = Completer();
  d.complete(c.future);
  print("shucks!");
}
```
from hanging the runtime by busily searching for the end of a cycle.

See https://github.com/dart-lang/sdk/issues/48225
Fixes #48225

TEST= refactoring covered by existing tests, few new tests.

Change-Id: Id9fc5af5fe011deb0af3e1e8a4ea3a91799f9da4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244241
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
2022-06-09 15:32:33 +00:00
..
cast_error [ddc] Add library URIs to cast failure messages 2021-04-09 22:24:43 +00:00
debugger Refactor _Future. 2022-06-09 15:32:33 +00:00
assertion_failure_message_test.dart
basic_assignment_test.dart
const_test.dart
developer_events_test.dart [vm] Expose whether extension stream has listeners, guard postEvent 2022-04-26 07:53:43 +00:00
hot_restart_expando_test.dart [ddc] Add a regression test for issue #45874 2021-05-11 22:14:28 +00:00
hot_restart_js_interop_test.dart
hot_restart_late_test.dart [ddc] Reset static fields on first get or set 2022-02-11 01:18:01 +00:00
hot_restart_static_test.dart [ddc] Adding support for static setters of const fields 2022-04-01 23:51:15 +00:00
hot_restart_test.dart
hot_restart_timer_test.dart
if_else_literal_compilation_test.dart [ddc] Avoid emitting dead branches in conditionals 2022-05-03 20:17:44 +00:00
js_interop_test.dart
libraries_part.dart
libraries_test.dart
no_such_method_errors_test.dart
runtime_utils.dart
runtime_utils_nnbd.dart
subtype_test.dart
subtype_weak_test.dart
type_normalization_test.dart
utils.dart
variance_subtype_test.dart
variance_test.dart
weak_null_safety_errors_test.dart