Fix assert in Future code to allow a Future<Future<int>>.

Fix the `lib_2/async/future_test` test which was otherwise failing everywhere.
Updated status files.

Change-Id: I4e277dd7d47692b92b3303bfdd7cfbde120a8f87
Reviewed-on: https://dart-review.googlesource.com/65080
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 4803de0..423242f 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -598,6 +598,20 @@
     _fail("Test error: $message");
   }
 
+  /// Checks that [object] has type [T].
+  static void type<T>(Object object, [String reason]) {
+    if (object is T) return;
+    String msg = _getMessage(reason);
+    _fail("Expect.type($object is $T$msg) fails, was ${object.runtimeType}");
+  }
+
+  /// Checks that [object] does not have type [T].
+  static void notType<T>(Object object, [String reason]) {
+    if (object is! T) return;
+    String msg = _getMessage(reason);
+    _fail("Expect.type($object is! $T$msg) fails, was ${object.runtimeType}");
+  }
+
   static String _getMessage(String reason) =>
       (reason == null) ? "" : ", '$reason'";
 
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 077ccf6..19ec045 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -475,7 +475,7 @@
 
   void _completeWithValue(T value) {
     assert(!_isComplete);
-    assert(value is! Future);
+    assert(value is! Future<T>);
 
     _FutureListener listeners = _removeListeners();
     _setValue(value);
diff --git a/tests/lib_2/async/future_test.dart b/tests/lib_2/async/future_test.dart
index 5a075e9..515adca 100644
--- a/tests/lib_2/async/future_test.dart
+++ b/tests/lib_2/async/future_test.dart
@@ -636,7 +636,6 @@
     Expect.equals("ERROR-tcwfe2", e);
     asyncEnd();
   });
-
 }
 
 void testCompleteErrorWithFuture() {
@@ -688,7 +687,8 @@
   completer.completeError(future);
   completer.future.then((_) {
     Expect.fail("Shouldn't happen");
-  }, onError: (Future f) {
+  }, onError: (e) {
+    Future f = e;
     f.then((v) {
       Expect.equals(42, v);
       asyncEnd();
@@ -888,7 +888,8 @@
       Expect.equals(e, 1);
       asyncEnd();
     });
-  }, onError: (int index, s) {
+  }, onError: (e, s) {
+    int index = e;
     Expect.isTrue(index == 0 || index == 2, "$index");
     Expect.isFalse(uncaughts[index]);
     uncaughts[index] = true;
@@ -977,7 +978,7 @@
 void testTypes() {
   // Test that future is a Future<int> and not something less precise.
   testType(name, future, [depth = 2]) {
-    var desc = "$name${".whenComplete"*(2-depth)}";
+    var desc = "$name${".whenComplete" * (2 - depth)}";
     Expect.isTrue(future is Future<int>, "$desc is Future<int>");
     Expect.isFalse(future is Future<String>, "$desc is! Future<String>");
     var stream = future.asStream();
@@ -995,12 +996,9 @@
         new Future<int>.delayed(Duration.zero, () => value));
     testType(
         "Future.microtask($value)", new Future<int>.microtask(() => value));
-    testType( //# 01: ok
-        "Future.sync($value)", new Future<int>.sync(() => value)); //# 01: continued
-    testType( //# 01: continued
-        "Future.sync(future($value))", //# 01: continued
-        new Future<int>.sync(//# 01: continued
-            () => new Future<int>.value(value))); //# 01: continued
+    testType("Future.sync($value)", new Future<int>.sync(() => value));
+    testType("Future.sync(future($value))",
+        new Future<int>.sync(() => new Future<int>.value(value)));
     testType("Future.value($value)", new Future<int>.value(value));
   }
   testType("Completer.future", new Completer<int>().future);
@@ -1100,6 +1098,33 @@
   }();
 }
 
+void testFutureOfFuture() async {
+  // Plain Future.
+  asyncStart();
+  var future = Future<Future<int>>.value(Future<int>.value(42));
+  Expect.type<Future<Future<int>>>(future);
+  future.then((innerFuture) {
+    Expect.type<Future<int>>(innerFuture);
+    innerFuture.then((number) {
+      Expect.equals(42, number);
+      asyncEnd();
+    });
+  });
+
+  // With completer.
+  asyncStart();
+  var completer = Completer<Future<int>>();
+  Expect.type<Future<Future<int>>>(completer.future);
+  completer.future.then((innerFuture) {
+    Expect.type<Future<int>>(innerFuture);
+    innerFuture.then((number) {
+      Expect.equals(42, number);
+      asyncEnd();
+    });
+  });
+  completer.complete(Future<int>.value(42));
+}
+
 main() {
   asyncStart();
 
@@ -1173,6 +1198,8 @@
 
   testFutureResult();
 
+  testFutureOfFuture();
+
   asyncEnd();
 }
 
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 624c36b..249a438 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -119,6 +119,7 @@
 isolate/spawn_uri_multi_test/none: RuntimeError # Issue 13544
 
 [ !$strong ]
+async/future_test: SkipByDesign # Uses Dart 2 syntax.
 async/stream_first_where_test/badType: MissingCompileTimeError
 async/stream_last_where_test/badType: MissingCompileTimeError
 mirrors/redirecting_factory_different_type_test/02: MissingCompileTimeError
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 457d621..e6abbd8 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -824,8 +824,6 @@
 
 [ $compiler == dart2js && $strong ]
 async/future_or_type_test: RuntimeError
-async/future_test/01: RuntimeError
-async/future_test/none: RuntimeError
 async/slow_consumer2_test: RuntimeError
 async/stream_controller_async_test: RuntimeError
 async/stream_distinct_test: RuntimeError
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index 93dd366..29fd51d 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -11,8 +11,6 @@
 # to add them.
 
 [ $compiler == app_jitk ]
-async/future_test/01: RuntimeError
-async/future_test/none: RuntimeError
 async/slow_consumer2_test: RuntimeError
 async/stream_controller_async_test: RuntimeError
 async/stream_distinct_test: RuntimeError
@@ -201,8 +199,6 @@
 isolate/pause_test: Skip # Timeout
 
 [ $compiler == dartk && $strong ]
-async/future_test/01: RuntimeError
-async/future_test/none: RuntimeError
 async/slow_consumer2_test: RuntimeError # Issue 31402 (Invocation arguments)
 async/stream_controller_async_test: RuntimeError
 async/stream_distinct_test: RuntimeError
@@ -304,8 +300,6 @@
 
 # ===== dartkp + dart_precompiled status lines =====
 [ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
-async/future_test/01: RuntimeError
-async/future_test/none: RuntimeError
 async/slow_consumer2_test: RuntimeError # Issue 31402 (Invocation arguments)
 async/stream_controller_async_test: RuntimeError
 async/stream_distinct_test: RuntimeError