Version 2.0.0-dev.69.3

Cherry-pick f3625375744979a4c65e289a3140cbdd7fbf6f32 to dev
Cherry-pick 7b77fa217b7b7e45ceb1d5ca820e18853b7728a4 to dev
Cherry-pick 071ca8c05c62d227b22d0c95a831bea98ec5aeb8 to dev
Cherry-pick 9727a4a4ef6a3c3de8cd6be75ab515643ee15bc6 to dev
Cherry-pick c353d02a3c1c26e78b17768e31e6093e6cbf538b to dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2116487..cca1d02 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 2.0.0-dev.69.3
+
+Cherry-pick f3625375744979a4c65e289a3140cbdd7fbf6f32 to dev
+Cherry-pick 7b77fa217b7b7e45ceb1d5ca820e18853b7728a4 to dev
+Cherry-pick 071ca8c05c62d227b22d0c95a831bea98ec5aeb8 to dev
+Cherry-pick 9727a4a4ef6a3c3de8cd6be75ab515643ee15bc6 to dev
+Cherry-pick c353d02a3c1c26e78b17768e31e6093e6cbf538b to dev
+
 ## 2.0.0-dev.69.2
 
 ### Core library changes
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e82fa74..caff028 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -398,6 +398,7 @@
       _errorReporter.reportErrorForToken(
           CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
     }
+    _checkForUseOfVoidResult(node.expression);
     return super.visitAwaitExpression(node);
   }
 
diff --git a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
index 92bc27e..f3c148e 100644
--- a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
@@ -1636,4 +1636,9 @@
   test_useOfVoidResult_variableDeclaration_method_ok() async {
     return super.test_useOfVoidResult_variableDeclaration_method_ok();
   }
+
+  @override
+  test_useOfVoidResult_await() async {
+    return super.test_useOfVoidResult_await();
+  }
 }
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 222f88e..1417d23 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -4489,4 +4489,15 @@
     await computeAnalysisResult(source);
     assertNoErrors(source);
   }
+
+  test_useOfVoidResult_await() async {
+    Source source = addSource(r'''
+main() async {
+  void x;
+  await x;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
+    verify([source]);
+  }
 }
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
index 46360f9..961d1d6 100644
--- a/pkg/async_helper/lib/async_helper.dart
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -23,6 +23,8 @@
 
 library async_helper;
 
+import 'dart:async';
+
 bool _initialized = false;
 int _asyncLevel = 0;
 
@@ -81,7 +83,7 @@
  *
  * [f] must return a [:Future:] for the test computation.
  */
-void asyncTest(f()) {
+Future<void> asyncTest(f()) {
   asyncStart();
-  f().then(asyncSuccess);
+  return f().then(asyncSuccess);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 854ac86..38db74e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -667,7 +667,12 @@
           ]);
     } else if (library.loader.target.backendTarget.strongMode &&
         declaredFunction?.typeParameters != null) {
-      var substitution = <TypeParameter, DartType>{};
+      var substitutionMap = <TypeParameter, DartType>{};
+      for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
+        substitutionMap[interfaceFunction.typeParameters[i]] =
+            new TypeParameterType(declaredFunction.typeParameters[i]);
+      }
+      Substitution substitution = Substitution.fromMap(substitutionMap);
       for (int i = 0; i < declaredFunction.typeParameters.length; ++i) {
         TypeParameter declaredParameter = declaredFunction.typeParameters[i];
         TypeParameter interfaceParameter = interfaceFunction.typeParameters[i];
@@ -679,7 +684,7 @@
             interfaceBound =
                 interfaceSubstitution.substituteType(interfaceBound);
           }
-          if (declaredBound != interfaceBound) {
+          if (declaredBound != substitution.substituteType(interfaceBound)) {
             addProblem(
                 templateOverrideTypeVariablesMismatch.withArguments(
                     "$name::${declaredMember.name.name}",
@@ -695,13 +700,10 @@
                 ]);
           }
         }
-        substitution[interfaceParameter] =
-            new TypeParameterType(declaredParameter);
       }
-      var newSubstitution = Substitution.fromMap(substitution);
       interfaceSubstitution = interfaceSubstitution == null
-          ? newSubstitution
-          : Substitution.combine(interfaceSubstitution, newSubstitution);
+          ? substitution
+          : Substitution.combine(interfaceSubstitution, substitution);
     }
     return interfaceSubstitution;
   }
diff --git a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
index d9a9cad..ea0190d 100644
--- a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
@@ -2,6 +2,7 @@
 // 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.
 
+import 'dart:async' show Future;
 import 'dart:io' show Directory, File;
 
 import 'package:expect/expect.dart' show Expect;
@@ -22,7 +23,7 @@
   }
 }
 
-void testDart2jsCompile() async {
+Future<void> testDart2jsCompile() async {
   final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
   final Uri invalidateUri = Uri.parse("package:compiler/src/filenames.dart");
   Uri normalDill = outDir.uri.resolve("dart2js.full.dill");
diff --git a/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart
new file mode 100644
index 0000000..3058fbf
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, 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.
+
+// This test checks that an override of a generic method is allowed in case of
+// correctly defined f-bounded type variables.
+
+class Foo<T extends Foo<T>> {}
+
+abstract class Bar {
+  void fisk<S extends Foo<S>>();
+}
+
+class Hest implements Bar {
+  @override
+  void fisk<U extends Foo<U>>() {}
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.direct.expect b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.direct.expect
new file mode 100644
index 0000000..b01aeb7
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.direct.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends self::Foo<self::Foo::T> = dynamic> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method fisk<S extends self::Foo<self::Bar::fisk::S> = dynamic>() → void;
+}
+class Hest extends core::Object implements self::Bar {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  method fisk<U extends self::Foo<self::Hest::fisk::U> = dynamic>() → void {}
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.direct.transformed.expect
new file mode 100644
index 0000000..b01aeb7
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends self::Foo<self::Foo::T> = dynamic> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method fisk<S extends self::Foo<self::Bar::fisk::S> = dynamic>() → void;
+}
+class Hest extends core::Object implements self::Bar {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  method fisk<U extends self::Foo<self::Hest::fisk::U> = dynamic>() → void {}
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.outline.expect b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.outline.expect
new file mode 100644
index 0000000..f6befa0
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.outline.expect
@@ -0,0 +1,21 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends self::Foo<self::Foo::T> = dynamic> extends core::Object {
+  synthetic constructor •() → void
+    ;
+}
+abstract class Bar extends core::Object {
+  synthetic constructor •() → void
+    ;
+  abstract method fisk<S extends self::Foo<self::Bar::fisk::S> = dynamic>() → void;
+}
+class Hest extends core::Object implements self::Bar {
+  synthetic constructor •() → void
+    ;
+  method fisk<U extends self::Foo<self::Hest::fisk::U> = dynamic>() → void
+    ;
+}
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.strong.expect b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.strong.expect
new file mode 100644
index 0000000..d4dc158
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.strong.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends self::Foo<self::Foo::T> = self::Foo<dynamic>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method fisk<S extends self::Foo<self::Bar::fisk::S> = self::Foo<dynamic>>() → void;
+}
+class Hest extends core::Object implements self::Bar {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  method fisk<U extends self::Foo<self::Hest::fisk::U> = self::Foo<dynamic>>() → void {}
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.strong.transformed.expect b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.strong.transformed.expect
new file mode 100644
index 0000000..d4dc158
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends self::Foo<self::Foo::T> = self::Foo<dynamic>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method fisk<S extends self::Foo<self::Bar::fisk::S> = self::Foo<dynamic>>() → void;
+}
+class Hest extends core::Object implements self::Bar {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  method fisk<U extends self::Foo<self::Hest::fisk::U> = self::Foo<dynamic>>() → void {}
+}
+static method main() → void {}
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 4c6eff1..1f4a615 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -731,9 +731,38 @@
   }
 
   void setValue(Type newValue, TypeFlowAnalysis typeFlowAnalysis) {
-    final Type newType = value.union(
-        newValue.intersection(staticType, typeFlowAnalysis.hierarchyCache),
-        typeFlowAnalysis.hierarchyCache);
+    // Make sure type cones are specialized before putting them into field
+    // value, in order to ensure that dependency is established between
+    // cone's base type and corresponding field setter.
+    //
+    // This ensures correct invalidation in the following scenario:
+    //
+    // 1) setValue(Cone(X)).
+    //    It sets field value to Cone(X).
+    //
+    // 2) setValue(Y).
+    //    It calculates Cone(X) U Y, specializing Cone(X).
+    //    This establishes class X --> setter(Y)  dependency.
+    //    If X does not have allocated subclasses, then Cone(X) is specialized
+    //    to Empty and the new field value is Y.
+    //
+    // 3) A new allocated subtype is added to X.
+    //    This invalidates setter(Y). However, recalculation of setter(Y)
+    //    does not yield correct field value, as value calculated on step 1 is
+    //    already lost, and repeating setValue(Y) will not change field value.
+    //
+    // The eager specialization of field value ensures that specialization
+    // will happen on step 1 and dependency class X --> setter(Cone(X))
+    // is established.
+    //
+    final hierarchy = typeFlowAnalysis.hierarchyCache;
+    Type newType = value
+        .union(
+            newValue.specialize(hierarchy).intersection(staticType, hierarchy),
+            hierarchy)
+        .specialize(hierarchy);
+    assertx(newType.isSpecialized);
+
     if (newType != value) {
       if (kPrintTrace) {
         tracePrint("Set field $field value $newType");
@@ -887,8 +916,8 @@
   @override
   bool isSubtype(DartType subType, DartType superType) {
     if (kPrintTrace) {
-      tracePrint("isSubtype for sub = $subType (${subType
-              .runtimeType}), sup = $superType (${superType.runtimeType})");
+      tracePrint("isSubtype for sub = $subType (${subType.runtimeType}),"
+          " sup = $superType (${superType.runtimeType})");
     }
     if (subType == superType) {
       return true;
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index e918a6d..f4a99d2 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -83,7 +83,9 @@
   Type get argumentType => _argumentType;
 
   void _observeArgumentType(Type argType, TypeHierarchy typeHierarchy) {
+    assertx(argType.isSpecialized);
     _argumentType = _argumentType.union(argType, typeHierarchy);
+    assertx(_argumentType.isSpecialized);
   }
 }
 
@@ -183,10 +185,11 @@
     if (selector is! DirectSelector) {
       _observeReceiverType(argTypes[0]);
     }
-    final Type result = callHandler.applyCall(
+    Type result = callHandler.applyCall(
         this, selector, new Args<Type>(argTypes, names: args.names),
         isResultUsed: isResultUsed);
     if (isResultUsed) {
+      result = result.specialize(typeHierarchy);
       _observeResultType(result, typeHierarchy);
     }
     return result;
@@ -252,7 +255,9 @@
   }
 
   void _observeResultType(Type result, TypeHierarchy typeHierarchy) {
+    assertx(result.isSpecialized);
     _resultType = _resultType.union(result, typeHierarchy);
+    assertx(_resultType.isSpecialized);
   }
 }
 
@@ -311,36 +316,37 @@
 
     List<Type> types = new List<Type>(_statements.length);
 
-    types.setRange(0, positionalArgCount, args);
-
     for (int i = 0; i < positionalArgCount; i++) {
-      Parameter param = _statements[i] as Parameter;
-      param._observeArgumentType(args[i], typeHierarchy);
-      types[i] = args[i].intersection(param.staticType, typeHierarchy);
+      final Parameter param = _statements[i] as Parameter;
+      final argType = args[i].specialize(typeHierarchy);
+      param._observeArgumentType(argType, typeHierarchy);
+      types[i] = argType.intersection(param.staticType, typeHierarchy);
     }
 
     for (int i = positionalArgCount; i < positionalParameterCount; i++) {
-      Parameter param = _statements[i] as Parameter;
-      assertx(param.defaultValue != null);
-      param._observeArgumentType(param.defaultValue, typeHierarchy);
-      types[i] = param.defaultValue;
+      final Parameter param = _statements[i] as Parameter;
+      final argType = param.defaultValue.specialize(typeHierarchy);
+      param._observeArgumentType(argType, typeHierarchy);
+      types[i] = argType;
     }
 
     final argNames = arguments.names;
     int argIndex = 0;
     for (int i = positionalParameterCount; i < parameterCount; i++) {
-      Parameter param = _statements[i] as Parameter;
+      final Parameter param = _statements[i] as Parameter;
       assertx(param.defaultValue != null);
       if ((argIndex < namedArgCount) && (argNames[argIndex] == param.name)) {
-        Type argType = args[positionalArgCount + argIndex];
+        final argType =
+            args[positionalArgCount + argIndex].specialize(typeHierarchy);
         argIndex++;
         param._observeArgumentType(argType, typeHierarchy);
         types[i] = argType.intersection(param.staticType, typeHierarchy);
       } else {
         assertx((argIndex == namedArgCount) ||
             (param.name.compareTo(argNames[argIndex]) < 0));
-        param._observeArgumentType(param.defaultValue, typeHierarchy);
-        types[i] = param.defaultValue;
+        final argType = param.defaultValue.specialize(typeHierarchy);
+        param._observeArgumentType(argType, typeHierarchy);
+        types[i] = argType;
       }
     }
     assertx(argIndex == namedArgCount);
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index a964682..2100c02 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -101,6 +101,12 @@
   /// Order of precedence for evaluation of union/intersection.
   int get order;
 
+  /// Returns true iff this type is fully specialized.
+  bool get isSpecialized => true;
+
+  /// Returns specialization of this type using the given [TypeHierarchy].
+  Type specialize(TypeHierarchy typeHierarchy) => this;
+
   /// Calculate union of this and [other] types.
   Type union(Type other, TypeHierarchy typeHierarchy);
 
@@ -165,6 +171,14 @@
   int get order => TypeOrder.Nullable.index;
 
   @override
+  bool get isSpecialized => baseType.isSpecialized;
+
+  @override
+  Type specialize(TypeHierarchy typeHierarchy) => baseType.isSpecialized
+      ? this
+      : new NullableType(baseType.specialize(typeHierarchy));
+
+  @override
   Type union(Type other, TypeHierarchy typeHierarchy) {
     if (other.order < this.order) {
       return other.union(this, typeHierarchy);
@@ -396,6 +410,13 @@
   int get order => TypeOrder.Cone.index;
 
   @override
+  bool get isSpecialized => false;
+
+  @override
+  Type specialize(TypeHierarchy typeHierarchy) =>
+      typeHierarchy.specializeTypeCone(dartType);
+
+  @override
   Type union(Type other, TypeHierarchy typeHierarchy) {
     if (other.order < this.order) {
       return other.union(this, typeHierarchy);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart
new file mode 100644
index 0000000..12cc624
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, 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.
+
+class T1 {
+  T3 go() => new T3();
+}
+
+class T2 {}
+
+class T3 {
+  run() {
+    print('hi');
+  }
+}
+
+class Q<T> {
+  final T result;
+  Q(this.result);
+}
+
+foo1(List<T1> list) {
+  list.map((T1 t1) => new Q<T1>(t1)).first.result.go().run();
+}
+
+Q foo2NewValue() => new Q<T2>(new T2());
+
+foo3NewT1() {
+  new T1();
+}
+
+main(List<String> args) {
+  foo1([]);
+  foo2NewValue();
+  foo3NewT1();
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
new file mode 100644
index 0000000..ac18742
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field2.dart.expect
@@ -0,0 +1,43 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class T1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method go() → self::T3
+    return new self::T3::•();
+}
+class T2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class T3 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method run() → dynamic {
+    core::print("hi");
+  }
+}
+class Q<T extends core::Object = dynamic> extends core::Object {
+  final field self::Q::T result;
+  constructor •(self::Q::T result) → void
+    : self::Q::result = result, super core::Object::•()
+    ;
+}
+static method foo1(core::List<self::T1> list) → dynamic {
+  [@vm.direct-call.metadata=#lib::T3::run] [@vm.direct-call.metadata=#lib::T1::go??] [@vm.inferred-type.metadata=#lib::T3] [@vm.direct-call.metadata=#lib::Q::result??] [@vm.inferred-type.metadata=!] list.{core::Iterable::map}<self::Q<self::T1>>((self::T1 t1) → self::Q<self::T1> => new self::Q::•<self::T1>(t1)).{core::Iterable::first}.{self::Q::result}.{self::T1::go}().{self::T3::run}();
+}
+static method foo2NewValue() → self::Q<dynamic>
+  return new self::Q::•<self::T2>(new self::T2::•());
+static method foo3NewT1() → dynamic {
+  new self::T1::•();
+}
+static method main(core::List<core::String> args) → dynamic {
+  self::foo1(<self::T1>[]);
+  self::foo2NewValue();
+  self::foo3NewT1();
+}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index b046d1b..6ec6ed5 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -14504,7 +14504,7 @@
 
 // WARNING: Do not edit - generated code.
 
-typedef void _EntriesCallback(List<Entry> entries);
+typedef void _EntriesCallback(List entries);
 // Copyright (c) 2012, 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.
@@ -18843,7 +18843,7 @@
 // WARNING: Do not edit - generated code.
 
 typedef void IntersectionObserverCallback(
-    List<IntersectionObserverEntry> entries, IntersectionObserver observer);
+    List entries, IntersectionObserver observer);
 // Copyright (c) 2012, 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.
@@ -21179,8 +21179,7 @@
 
 // WARNING: Do not edit - generated code.
 
-typedef void MutationCallback(
-    List<MutationRecord> mutations, MutationObserver observer);
+typedef void MutationCallback(List mutations, MutationObserver observer);
 // Copyright (c) 2012, 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.
@@ -25106,7 +25105,7 @@
 // WARNING: Do not edit - generated code.
 
 typedef void ReportingObserverCallback(
-    List<_Report> reports, ReportingObserver observer);
+    List reports, ReportingObserver observer);
 // Copyright (c) 2012, 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.
@@ -25481,7 +25480,6 @@
   * Temporarily exposes _getStats and old getStats as getLegacyStats until Chrome fully supports
   * new getStats API.
   */
-  @JSName('getStats')
   Future<RtcStatsResponse> getLegacyStats([MediaStreamTrack selector]) {
     var completer = new Completer<RtcStatsResponse>();
     _getStats((value) {
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status
index d94473f..bbb17dd 100644
--- a/tests/co19_2/co19_2-analyzer.status
+++ b/tests/co19_2/co19_2-analyzer.status
@@ -2782,6 +2782,9 @@
 LibTest/io/RandomAccessFile/writeString_A01_t03: CompileTimeError # Dart 1 constants, https://github.com/dart-lang/sdk/issues/33894
 LibTest/io/Stdin/readLineSync_A03_t01: CompileTimeError # Dart 1 constants, https://github.com/dart-lang/sdk/issues/33894
 LibTest/io/Stdin/readLineSync_A03_t02: CompileTimeError # Dart 1 constants, https://github.com/dart-lang/sdk/issues/33894
+LibTest/io/Stdin/readLineSync_A03_t03: CompileTimeError # Erroneously awaits void
+LibTest/io/Stdin/readLineSync_A03_t04: CompileTimeError # Erroneously awaits void
+LibTest/io/Stdin/readLineSync_A04_t01: CompileTimeError # Erroneously awaits void
 LibTest/io/Stdout/add_A02_t01: CompileTimeError # Dart 1 constants, https://github.com/dart-lang/sdk/issues/33894
 LibTest/io/Stdout/encoding_A01_t01: CompileTimeError # Dart 1 constants, https://github.com/dart-lang/sdk/issues/33894
 LibTest/io/Stdout/writeAll_A01_t02: CompileTimeError # Dart 1 constants, https://github.com/dart-lang/sdk/issues/33894
diff --git a/tests/lib_2/html/callback_list_test.dart b/tests/lib_2/html/callback_list_test.dart
new file mode 100644
index 0000000..71e0902
--- /dev/null
+++ b/tests/lib_2/html/callback_list_test.dart
@@ -0,0 +1,42 @@
+library callback_list_test;
+
+import 'dart:html';
+import 'dart:async';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+var callbackDone = false;
+bool isCallbackDone() => callbackDone;
+
+Future waitUntilCallbackDone(bool test()) async {
+  var completer = new Completer();
+  check() {
+    if (test()) {
+      completer.complete();
+    } else {
+      new Timer(Duration.zero, check);
+    }
+  }
+
+  check();
+  return completer.future;
+}
+
+void main() async {
+  useHtmlConfiguration();
+  window.navigator.persistentStorage.requestQuota(1024 * 1024, _quotaHandler);
+
+  await waitUntilCallbackDone(isCallbackDone);
+  expect(true, isCallbackDone());
+}
+
+Future _quotaHandler(int byteCount) async {
+  FileSystem filesystem =
+      await window.requestFileSystem(1024 * 1024, persistent: true);
+  DirectoryEntry dir = await filesystem.root;
+  DirectoryReader dirReader = dir.createReader();
+  await dirReader.readEntries();
+  List<Entry> secondEntries = await dirReader.readEntries();
+  callbackDone = true;
+}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 9e3bf1c..80e194f715 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -87,7 +87,6 @@
 html/worker_test/functional: RuntimeError # Issue 32261
 
 [ $compiler == dart2js && $runtime == chrome && $strong ]
-html/fileapi_directory_reader_test: RuntimeError
 html/interactive_media_test: RuntimeError
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
@@ -117,6 +116,7 @@
 html/b_element_test: RuntimeError
 html/blob_constructor_test: RuntimeError
 html/cache_test: RuntimeError
+html/callback_list_test: RuntimeError
 html/callbacks_test: RuntimeError
 html/canvas_pixel_array_type_alias_test: RuntimeError
 html/canvas_test: RuntimeError
@@ -358,6 +358,7 @@
 convert/streamed_conversion_json_utf8_encode_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_utf8_decode_test: SkipSlow # Times out. Issue 22050
 convert/utf85_test: Pass, Slow, Timeout
+html/callback_list_test: SkipByDesign # FileSystem not supported in FireFox.
 html/custom/attribute_changed_callback_test: Skip # Times out
 html/custom/constructor_calls_created_synchronously_test: Pass, Timeout
 html/custom/created_callback_test: Skip # Times out
@@ -461,6 +462,7 @@
 
 [ $compiler == dart2js && $runtime == safari ]
 html/audiobuffersourcenode_test: RuntimeError
+html/callback_list_test: SkipByDesign # FileSystem not supported in Safari.
 html/css_test/functional/functional: RuntimeError # Issue 32576
 html/custom/attribute_changed_callback_test: RuntimeError, Timeout
 html/custom/constructor_calls_created_synchronously_test: Pass, Timeout
diff --git a/tools/VERSION b/tools/VERSION
index e1e08c0..0ebcd39 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,5 @@
 MINOR 0
 PATCH 0
 PRERELEASE 69
-PRERELEASE_PATCH 2
+PRERELEASE_PATCH 3
+*
\ No newline at end of file
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 7b7dabf..0fcf00a 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -137,6 +137,15 @@
 # constructor creation.
 _static_classes = set(['Url'])
 
+# Callback typedefs with generic List (List<nnn>) convert to List
+_callback_list_generics_mapping = monitored.Set('systemhtml._callback_list_generics_mapping', [
+    'List<Entry>',
+    'List<IntersectionObserverEntry>',
+    'List<MutationRecord>',
+    'List<_Report>',
+])
+
+
 # Information for generating element constructors.
 #
 # TODO(sra): maybe remove all the argument complexity and use cascades.
@@ -524,10 +533,19 @@
     annotations = self._metadata.GetFormattedMetadata(self._library_name,
         self._interface)
 
+    params = info.ParametersAsDeclaration(self._DartType);
+
+    types = params.split()
+    if len(types) > 0:
+      mapType = types[0] in _callback_list_generics_mapping
+      if mapType is True:
+        types[0] = 'List'
+        params = " ".join(types)
+
     code.Emit('$(ANNOTATIONS)typedef void $NAME($PARAMS);\n',
               ANNOTATIONS=annotations,
               NAME=typedef_name,
-              PARAMS=info.ParametersAsDeclaration(self._DartType))
+              PARAMS=params)
     self._backend.GenerateCallback(info)
 
   def GenerateInterface(self):
diff --git a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
index 293fb19..33f503a 100644
--- a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
+++ b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
@@ -54,7 +54,6 @@
   * Temporarily exposes _getStats and old getStats as getLegacyStats until Chrome fully supports
   * new getStats API.
   */
-  @JSName('getStats')
   Future<RtcStatsResponse> getLegacyStats([MediaStreamTrack selector]) {
     var completer = new Completer<RtcStatsResponse>();
     _getStats((value) {
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
index e32065c..b4ca60d 100644
--- a/tools/patch_sdk.dart
+++ b/tools/patch_sdk.dart
@@ -146,7 +146,7 @@
       throw "Unknown mode: $mode";
   }
 
-  await _writeSync(
+  _writeSync(
       librariesJson.toFilePath(),
       jsonEncode({
         mode: {"libraries": locations}