Version 2.13.0-94.0.dev

Merge commit 'f3740ced59abc400e718bdfa4bd8020e9516d0fa' into 'dev'
diff --git a/pkg/compiler/lib/src/io/location_provider.dart b/pkg/compiler/lib/src/io/location_provider.dart
index fff55c5..4f36c5e 100644
--- a/pkg/compiler/lib/src/io/location_provider.dart
+++ b/pkg/compiler/lib/src/io/location_provider.dart
@@ -40,7 +40,8 @@
   @override
   Location getLocation(int offset) {
     RangeError.checkValueInInterval(offset, 0, length, 'offset');
-    return new Source(lineStarts, null, null, null).getLocation(null, offset);
+    return new Source(lineStarts, const <int>[], null, null)
+        .getLocation(null, offset);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index da7aea2..1e93f43 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -125,8 +125,8 @@
       Reference fieldSetterReference,
       Reference lateIsSetGetterReference,
       Reference lateIsSetSetterReference,
-      Reference getterReference,
-      Reference setterReference})
+      Reference lateGetterReference,
+      Reference lateSetterReference})
       : super(libraryBuilder, charOffset) {
     Uri fileUri = libraryBuilder?.fileUri;
     // If in mixed mode, late lowerings cannot use `null` as a sentinel on
@@ -134,8 +134,12 @@
     late_lowering.IsSetStrategy isSetStrategy =
         late_lowering.computeIsSetStrategy(libraryBuilder);
     if (isAbstract || isExternal) {
-      _fieldEncoding = new AbstractOrExternalFieldEncoding(
-          fileUri, charOffset, charEndOffset, getterReference, setterReference,
+      assert(lateIsSetGetterReference == null);
+      assert(lateIsSetSetterReference == null);
+      assert(lateGetterReference == null);
+      assert(lateSetterReference == null);
+      _fieldEncoding = new AbstractOrExternalFieldEncoding(fileUri, charOffset,
+          charEndOffset, fieldGetterReference, fieldSetterReference,
           isAbstract: isAbstract,
           isExternal: isExternal,
           isFinal: isFinal,
@@ -157,8 +161,8 @@
               fieldSetterReference,
               lateIsSetGetterReference,
               lateIsSetSetterReference,
-              getterReference,
-              setterReference,
+              lateGetterReference,
+              lateSetterReference,
               isCovariant,
               isSetStrategy);
         } else {
@@ -171,8 +175,8 @@
               fieldSetterReference,
               lateIsSetGetterReference,
               lateIsSetSetterReference,
-              getterReference,
-              setterReference,
+              lateGetterReference,
+              lateSetterReference,
               isCovariant,
               isSetStrategy);
         }
@@ -187,8 +191,8 @@
               fieldSetterReference,
               lateIsSetGetterReference,
               lateIsSetSetterReference,
-              getterReference,
-              setterReference,
+              lateGetterReference,
+              lateSetterReference,
               isCovariant,
               isSetStrategy);
         } else {
@@ -201,8 +205,8 @@
               fieldSetterReference,
               lateIsSetGetterReference,
               lateIsSetSetterReference,
-              getterReference,
-              setterReference,
+              lateGetterReference,
+              lateSetterReference,
               isCovariant,
               isSetStrategy);
         }
@@ -222,8 +226,8 @@
             fieldSetterReference,
             lateIsSetGetterReference,
             lateIsSetSetterReference,
-            getterReference,
-            setterReference,
+            lateGetterReference,
+            lateSetterReference,
             isCovariant,
             isSetStrategy);
       } else {
@@ -236,16 +240,16 @@
             fieldSetterReference,
             lateIsSetGetterReference,
             lateIsSetSetterReference,
-            getterReference,
-            setterReference,
+            lateGetterReference,
+            lateSetterReference,
             isCovariant,
             isSetStrategy);
       }
     } else {
       assert(lateIsSetGetterReference == null);
       assert(lateIsSetSetterReference == null);
-      assert(getterReference == null);
-      assert(setterReference == null);
+      assert(lateGetterReference == null);
+      assert(lateSetterReference == null);
       _fieldEncoding = new RegularFieldEncoding(
           fileUri, charOffset, charEndOffset,
           isFinal: isFinal,
@@ -838,8 +842,8 @@
       Reference fieldSetterReference,
       Reference lateIsSetGetterReference,
       Reference lateIsSetSetterReference,
-      Reference getterReference,
-      Reference setterReference,
+      Reference lateGetterReference,
+      Reference lateSetterReference,
       bool isCovariant,
       late_lowering.IsSetStrategy isSetStrategy)
       : fileOffset = charOffset,
@@ -879,11 +883,11 @@
           ..fileOffset = charOffset
           ..fileEndOffset = charEndOffset,
         fileUri: fileUri,
-        reference: getterReference)
+        reference: lateGetterReference)
       ..fileOffset = charOffset
       ..fileEndOffset = charEndOffset
       ..isNonNullableByDefault = true;
-    _lateSetter = _createSetter(name, fileUri, charOffset, setterReference,
+    _lateSetter = _createSetter(name, fileUri, charOffset, lateSetterReference,
         isCovariant: isCovariant);
   }
 
@@ -1251,8 +1255,8 @@
       Reference fieldSetterReference,
       Reference lateIsSetGetterReference,
       Reference lateIsSetSetterReference,
-      Reference getterReference,
-      Reference setterReference,
+      Reference lateGetterReference,
+      Reference lateSetterReference,
       bool isCovariant,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
@@ -1264,8 +1268,8 @@
             fieldSetterReference,
             lateIsSetGetterReference,
             lateIsSetSetterReference,
-            getterReference,
-            setterReference,
+            lateGetterReference,
+            lateSetterReference,
             isCovariant,
             isSetStrategy);
 }
@@ -1281,8 +1285,8 @@
       Reference fieldSetterReference,
       Reference lateIsSetGetterReference,
       Reference lateIsSetSetterReference,
-      Reference getterReference,
-      Reference setterReference,
+      Reference lateGetterReference,
+      Reference lateSetterReference,
       bool isCovariant,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
@@ -1294,8 +1298,8 @@
             fieldSetterReference,
             lateIsSetGetterReference,
             lateIsSetSetterReference,
-            getterReference,
-            setterReference,
+            lateGetterReference,
+            lateSetterReference,
             isCovariant,
             isSetStrategy);
 
@@ -1326,8 +1330,8 @@
       Reference fieldSetterReference,
       Reference lateIsSetGetterReference,
       Reference lateIsSetSetterReference,
-      Reference getterReference,
-      Reference setterReference,
+      Reference lateGetterReference,
+      Reference lateSetterReference,
       bool isCovariant,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
@@ -1339,8 +1343,8 @@
             fieldSetterReference,
             lateIsSetGetterReference,
             lateIsSetSetterReference,
-            getterReference,
-            setterReference,
+            lateGetterReference,
+            lateSetterReference,
             isCovariant,
             isSetStrategy);
 
@@ -1372,8 +1376,8 @@
       Reference fieldSetterReference,
       Reference lateIsSetGetterReference,
       Reference lateIsSetSetterReference,
-      Reference getterReference,
-      Reference setterReference,
+      Reference lateGetterReference,
+      Reference lateSetterReference,
       bool isCovariant,
       late_lowering.IsSetStrategy isSetStrategy)
       : super(
@@ -1385,8 +1389,8 @@
             fieldSetterReference,
             lateIsSetGetterReference,
             lateIsSetSetterReference,
-            getterReference,
-            setterReference,
+            lateGetterReference,
+            lateSetterReference,
             isCovariant,
             isSetStrategy);
   @override
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index eaabec0..9965154 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -1047,8 +1047,8 @@
               .isNonNullableByDefault /* depends on language version etc */,
           enableTripleShift:
               /* should this be on the library? */
-              /* this is what the constant evaluator does */
-              userCode
+              /* this is effectively what the constant evaluator does */
+              context.options
                   .isExperimentEnabledGlobally(ExperimentalFlag.tripleShift));
       String before = textualOutline(previousSource, scannerConfiguration,
           performModelling: true);
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index 86496d4..d3c6b5a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -335,7 +335,8 @@
               assert(
                   _combinedMemberSignatureType != null,
                   "No combined member signature found for "
-                  "${_mutualSubtypes.values.map((int i) => getMemberType(i))}");
+                  "${_mutualSubtypes.values.map((int i) => getMemberType(i))} "
+                  "for members ${members}");
             }
           }
           _neededNnbdTopMerge =
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index c4a855e..e3158d4 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -2141,8 +2141,8 @@
     Reference fieldSetterReference;
     Reference lateIsSetGetterReference;
     Reference lateIsSetSetterReference;
-    Reference getterReference;
-    Reference setterReference;
+    Reference lateGetterReference;
+    Reference lateSetterReference;
     if (referencesFrom != null) {
       String nameToLookup = SourceFieldBuilder.createFieldName(
           FieldNameType.Field, name,
@@ -2172,7 +2172,7 @@
             indexedContainer.lookupGetterReference(lateIsSetNameName);
         lateIsSetSetterReference =
             indexedContainer.lookupSetterReference(lateIsSetNameName);
-        getterReference = indexedContainer.lookupGetterReference(new Name(
+        lateGetterReference = indexedContainer.lookupGetterReference(new Name(
             SourceFieldBuilder.createFieldName(FieldNameType.Getter, name,
                 isInstanceMember: isInstanceMember,
                 className: className,
@@ -2180,7 +2180,7 @@
                 extensionName: extensionName,
                 isSynthesized: fieldIsLateWithLowering),
             indexedContainer.library));
-        setterReference = indexedContainer.lookupSetterReference(new Name(
+        lateSetterReference = indexedContainer.lookupSetterReference(new Name(
             SourceFieldBuilder.createFieldName(FieldNameType.Setter, name,
                 isInstanceMember: isInstanceMember,
                 className: className,
@@ -2197,8 +2197,8 @@
         fieldSetterReference: fieldSetterReference,
         lateIsSetGetterReference: lateIsSetGetterReference,
         lateIsSetSetterReference: lateIsSetSetterReference,
-        getterReference: getterReference,
-        setterReference: setterReference);
+        lateGetterReference: lateGetterReference,
+        lateSetterReference: lateSetterReference);
     fieldBuilder.constInitializerToken = constInitializerToken;
     addBuilder(name, fieldBuilder, charOffset,
         getterReference: fieldGetterReference,
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart
new file mode 100644
index 0000000..420dd920
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2021, 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 A {
+  void method1(C c) {}
+  void method2(int a, int b) {}
+}
+
+class B {
+  void method1(Unresolved c) {}
+  void method2(int a) {}
+}
+
+class C {}
+
+abstract class D implements A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.strong.expect b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.strong.expect
new file mode 100644
index 0000000..c80806c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.strong.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: Type 'Unresolved' not found.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:17:16: Error: Class 'D' inherits multiple members named 'method2' with incompatible signatures.
+// Try adding a declaration of 'method2' to 'D'.
+// abstract class D implements A, B {}
+//                ^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:7:8: Context: This is one of the overridden members.
+//   void method2(int a, int b) {}
+//        ^^^^^^^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:12:8: Context: This is one of the overridden members.
+//   void method2(int a) {}
+//        ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: 'Unresolved' isn't a type.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method method1(self::C c) → void {}
+  method method2(core::int a, core::int b) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method method1(invalid-type c) → void {}
+  method method2(core::int a) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class D extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  abstract member-signature method method1(invalid-type c) → void; -> self::A::method1
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.strong.transformed.expect
new file mode 100644
index 0000000..c80806c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.strong.transformed.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: Type 'Unresolved' not found.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:17:16: Error: Class 'D' inherits multiple members named 'method2' with incompatible signatures.
+// Try adding a declaration of 'method2' to 'D'.
+// abstract class D implements A, B {}
+//                ^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:7:8: Context: This is one of the overridden members.
+//   void method2(int a, int b) {}
+//        ^^^^^^^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:12:8: Context: This is one of the overridden members.
+//   void method2(int a) {}
+//        ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: 'Unresolved' isn't a type.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method method1(self::C c) → void {}
+  method method2(core::int a, core::int b) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method method1(invalid-type c) → void {}
+  method method2(core::int a) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class D extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  abstract member-signature method method1(invalid-type c) → void; -> self::A::method1
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.textual_outline.expect
new file mode 100644
index 0000000..a440beb
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.textual_outline.expect
@@ -0,0 +1,15 @@
+class A {
+  void method1(C c) {}
+  void method2(int a, int b) {}
+}
+
+class B {
+  void method1(Unresolved c) {}
+  void method2(int a) {}
+}
+
+class C {}
+
+abstract class D implements A, B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4435f2b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.textual_outline_modelled.expect
@@ -0,0 +1,15 @@
+abstract class D implements A, B {}
+
+class A {
+  void method1(C c) {}
+  void method2(int a, int b) {}
+}
+
+class B {
+  void method1(Unresolved c) {}
+  void method2(int a) {}
+}
+
+class C {}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.expect b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.expect
new file mode 100644
index 0000000..c80806c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: Type 'Unresolved' not found.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:17:16: Error: Class 'D' inherits multiple members named 'method2' with incompatible signatures.
+// Try adding a declaration of 'method2' to 'D'.
+// abstract class D implements A, B {}
+//                ^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:7:8: Context: This is one of the overridden members.
+//   void method2(int a, int b) {}
+//        ^^^^^^^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:12:8: Context: This is one of the overridden members.
+//   void method2(int a) {}
+//        ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: 'Unresolved' isn't a type.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method method1(self::C c) → void {}
+  method method2(core::int a, core::int b) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method method1(invalid-type c) → void {}
+  method method2(core::int a) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class D extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  abstract member-signature method method1(invalid-type c) → void; -> self::A::method1
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.outline.expect
new file mode 100644
index 0000000..1fa2ce4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.outline.expect
@@ -0,0 +1,49 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: Type 'Unresolved' not found.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:17:16: Error: Class 'D' inherits multiple members named 'method2' with incompatible signatures.
+// Try adding a declaration of 'method2' to 'D'.
+// abstract class D implements A, B {}
+//                ^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:7:8: Context: This is one of the overridden members.
+//   void method2(int a, int b) {}
+//        ^^^^^^^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:12:8: Context: This is one of the overridden members.
+//   void method2(int a) {}
+//        ^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method method1(self::C c) → void
+    ;
+  method method2(core::int a, core::int b) → void
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+  method method1(invalid-type c) → void
+    ;
+  method method2(core::int a) → void
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+}
+abstract class D extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::D
+    ;
+  abstract member-signature method method1(invalid-type c) → void; -> self::A::method1
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.transformed.expect
new file mode 100644
index 0000000..c80806c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart.weak.transformed.expect
@@ -0,0 +1,52 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: Type 'Unresolved' not found.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:17:16: Error: Class 'D' inherits multiple members named 'method2' with incompatible signatures.
+// Try adding a declaration of 'method2' to 'D'.
+// abstract class D implements A, B {}
+//                ^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:7:8: Context: This is one of the overridden members.
+//   void method2(int a, int b) {}
+//        ^^^^^^^
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:12:8: Context: This is one of the overridden members.
+//   void method2(int a) {}
+//        ^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/invalid_combined_member_signature.dart:11:16: Error: 'Unresolved' isn't a type.
+//   void method1(Unresolved c) {}
+//                ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method method1(self::C c) → void {}
+  method method2(core::int a, core::int b) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method method1(invalid-type c) → void {}
+  method method2(core::int a) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class D extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  abstract member-signature method method1(invalid-type c) → void; -> self::A::method1
+}
+static method main() → dynamic {}
diff --git a/pkg/kernel/bin/size_breakdown.dart b/pkg/kernel/bin/size_breakdown.dart
index 979b828..79fbefa 100755
--- a/pkg/kernel/bin/size_breakdown.dart
+++ b/pkg/kernel/bin/size_breakdown.dart
@@ -64,9 +64,9 @@
     linkTableSize += byteOffset;
   }
 
-  Map<Uri, Source> readUriToSource(bool readCoverage) {
+  Map<Uri, Source> readUriToSource({bool readCoverage}) {
     uriToSourceSize -= byteOffset;
-    var result = super.readUriToSource(readCoverage);
+    var result = super.readUriToSource(readCoverage: readCoverage);
     uriToSourceSize += byteOffset;
     return result;
   }
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 47f4628..b350f3f 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -2243,6 +2243,7 @@
 
   /// Reference to the constructor or the factory that this
   /// [RedirectingFactoryConstructor] redirects to.
+  // TODO(johnniwinther): Make this non-nullable.
   Reference? targetReference;
 
   /// [typeParameters] are duplicates of the type parameters of the enclosing
@@ -2630,7 +2631,7 @@
   ProcedureStubKind stubKind;
   Reference? stubTargetReference;
 
-  Procedure(Name? name, ProcedureKind kind, FunctionNode function,
+  Procedure(Name? name, ProcedureKind kind, FunctionNode? function,
       {bool isAbstract: false,
       bool isStatic: false,
       bool isExternal: false,
@@ -3694,7 +3695,8 @@
 /// The [fileOffset] of an [InvalidExpression] indicates the location in the
 /// tree where the expression occurs, rather than the location of the error.
 class InvalidExpression extends Expression {
-  String message;
+  // TODO(johnniwinther): Avoid using `null` as the empty string.
+  String? message;
 
   InvalidExpression(this.message);
 
@@ -3730,7 +3732,7 @@
   @override
   void toTextInternal(AstPrinter printer) {
     printer.write('<invalid:');
-    printer.write(message);
+    printer.write(message ?? '');
     printer.write('>');
   }
 }
@@ -12090,7 +12092,7 @@
 
 class SymbolConstant extends Constant {
   final String name;
-  final Reference libraryReference;
+  final Reference? libraryReference;
 
   SymbolConstant(this.name, this.libraryReference);
 
@@ -12116,9 +12118,8 @@
   @override
   void toTextInternal(AstPrinter printer) {
     printer.write('#');
-    // ignore: unnecessary_null_comparison
     if (printer.includeAuxiliaryProperties && libraryReference != null) {
-      printer.write(libraryNameToString(libraryReference.asLibrary));
+      printer.write(libraryNameToString(libraryReference!.asLibrary));
       printer.write('::');
     }
     printer.write(name);
@@ -12636,7 +12637,7 @@
 
   Procedure? get mainMethod => mainMethodName?.asProcedure;
 
-  void setMainMethodAndMode(Reference main, bool overwriteMainIfSet,
+  void setMainMethodAndMode(Reference? main, bool overwriteMainIfSet,
       NonNullableByDefaultCompiledMode mode) {
     if (_mainMethodName == null || overwriteMainIfSet) {
       _mainMethodName = main;
@@ -12718,7 +12719,7 @@
   String get tag;
 
   /// Mutable mapping between nodes and their metadata.
-  Map<TreeNode, T> get mapping;
+  Map<Node, T> get mapping;
 
   /// Write [metadata] object corresponding to the given [Node] into
   /// the given [BinarySink].
@@ -12749,7 +12750,7 @@
   /// Currently due to binary format specifics Catch and MapEntry nodes
   /// can't have metadata attached to them. Also, metadata is not saved on
   /// Block nodes inside BlockExpressions.
-  static bool isSupported(TreeNode node) {
+  static bool isSupported(Node node) {
     return !(node is MapEntry ||
         node is Catch ||
         (node is Block && node.parent is BlockExpression));
@@ -12796,7 +12797,7 @@
   /// Read List<Byte> from the source.
   List<int> readByteList();
 
-  CanonicalName readCanonicalNameReference();
+  CanonicalName? readNullableCanonicalNameReference();
   String readStringReference();
   Name readName();
   DartType readDartType();
@@ -12849,11 +12850,11 @@
   final List<int>? lineStarts;
 
   /// A UTF8 encoding of the original source file.
-  final List<int>? source;
+  final List<int> source;
 
-  final Uri importUri;
+  final Uri? importUri;
 
-  final Uri fileUri;
+  final Uri? fileUri;
 
   Set<Reference>? constantCoverageConstructors;
 
@@ -12865,16 +12866,13 @@
   /// number. The returned line contains no line separators.
   String? getTextLine(int line) {
     List<int>? lineStarts = this.lineStarts;
-    if (source == null ||
-        source!.isEmpty ||
-        lineStarts == null ||
-        lineStarts.isEmpty) {
+    if (source.isEmpty || lineStarts == null || lineStarts.isEmpty) {
       return null;
     }
     RangeError.checkValueInInterval(line, 1, lineStarts.length, 'line');
 
     String cachedText =
-        this.cachedText ??= utf8.decode(source!, allowMalformed: true);
+        this.cachedText ??= utf8.decode(source, allowMalformed: true);
     // -1 as line numbers start at 1.
     int index = line - 1;
     if (index + 1 == lineStarts.length) {
@@ -13113,7 +13111,7 @@
     return finish(combine2(value1, value2, hash));
   }
 
-  static int hash2(Object object1, Object object2) {
+  static int hash2(Object object1, Object? object2) {
     return combine2Finish(object2.hashCode, object2.hashCode, 0);
   }
 
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 911ea5a..7da0618 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2,8 +2,6 @@
 // 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.9
-
 library kernel.ast_from_binary;
 
 import 'dart:developer';
@@ -15,18 +13,19 @@
 import 'tag.dart';
 
 class ParseError {
-  String filename;
-  int byteIndex;
-  String message;
-  String path;
+  final String? filename;
+  final int byteIndex;
+  final String message;
+  final String path;
 
-  ParseError(this.message, {this.filename, this.byteIndex, this.path});
+  ParseError(this.message,
+      {required this.filename, required this.byteIndex, required this.path});
 
   String toString() => '$filename:$byteIndex: $message at $path';
 }
 
 class InvalidKernelVersionError {
-  final String filename;
+  final String? filename;
   final int version;
 
   InvalidKernelVersionError(this.filename, this.version);
@@ -78,17 +77,30 @@
 class _ComponentIndex {
   static const int numberOfFixedFields = 10;
 
-  int binaryOffsetForSourceTable;
-  int binaryOffsetForCanonicalNames;
-  int binaryOffsetForMetadataPayloads;
-  int binaryOffsetForMetadataMappings;
-  int binaryOffsetForStringTable;
-  int binaryOffsetForConstantTable;
-  int mainMethodReference;
-  NonNullableByDefaultCompiledMode compiledMode;
-  List<int> libraryOffsets;
-  int libraryCount;
-  int componentFileSizeInBytes;
+  final int binaryOffsetForSourceTable;
+  final int binaryOffsetForCanonicalNames;
+  final int binaryOffsetForMetadataPayloads;
+  final int binaryOffsetForMetadataMappings;
+  final int binaryOffsetForStringTable;
+  final int binaryOffsetForConstantTable;
+  final int mainMethodReference;
+  final NonNullableByDefaultCompiledMode compiledMode;
+  final List<int> libraryOffsets;
+  final int libraryCount;
+  final int componentFileSizeInBytes;
+
+  _ComponentIndex(
+      {required this.binaryOffsetForSourceTable,
+      required this.binaryOffsetForCanonicalNames,
+      required this.binaryOffsetForMetadataPayloads,
+      required this.binaryOffsetForMetadataMappings,
+      required this.binaryOffsetForStringTable,
+      required this.binaryOffsetForConstantTable,
+      required this.mainMethodReference,
+      required this.compiledMode,
+      required this.libraryOffsets,
+      required this.libraryCount,
+      required this.componentFileSizeInBytes});
 }
 
 class SubComponentView {
@@ -119,17 +131,17 @@
   int switchCaseStackBase = 0;
   final List<SwitchCase> switchCaseStack = <SwitchCase>[];
   final List<TypeParameter> typeParameterStack = <TypeParameter>[];
-  final String filename;
+  final String? filename;
   final List<int> _bytes;
   int _byteOffset = 0;
   final List<String> _stringTable = <String>[];
-  final List<Uri> _sourceUriTable = <Uri>[];
+  final List<Uri?> _sourceUriTable = <Uri>[];
   Map<int, Constant> _constantTable = <int, Constant>{};
-  List<CanonicalName> _linkTable;
+  late List<CanonicalName> _linkTable;
   int _transformerFlags = 0;
-  Library _currentLibrary;
+  Library? _currentLibrary;
   int _componentStartOffset = 0;
-  NonNullableByDefaultCompiledMode compilationMode;
+  NonNullableByDefaultCompiledMode? compilationMode;
 
   // If something goes wrong, this list should indicate what library,
   // class, and member was being built.
@@ -149,7 +161,7 @@
 
   /// [stringInterner] (optional) may be used to allow components to share
   /// instances of [String] that have the same contents.
-  final StringInterner /*?*/ stringInterner;
+  final StringInterner? stringInterner;
 
   /// When creating lists that *might* be growable, use this boolean as the
   /// setting to pass to `growable` so the dill can be loaded in a more compact
@@ -162,7 +174,7 @@
       {this.filename,
       bool disableLazyReading = false,
       bool disableLazyClassReading = false,
-      bool alwaysCreateNewNamedNodes,
+      bool? alwaysCreateNewNamedNodes,
       this.stringInterner,
       this.useGrowableLists = true})
       : _disableLazyReading = disableLazyReading,
@@ -211,18 +223,19 @@
   }
 
   final Float64List _doubleBuffer = new Float64List(1);
-  Uint8List _doubleBufferUint8;
+  Uint8List? _doubleBufferUint8;
 
   double readDouble() {
-    _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
-    _doubleBufferUint8[0] = readByte();
-    _doubleBufferUint8[1] = readByte();
-    _doubleBufferUint8[2] = readByte();
-    _doubleBufferUint8[3] = readByte();
-    _doubleBufferUint8[4] = readByte();
-    _doubleBufferUint8[5] = readByte();
-    _doubleBufferUint8[6] = readByte();
-    _doubleBufferUint8[7] = readByte();
+    Uint8List doubleBufferUint8 =
+        _doubleBufferUint8 ??= _doubleBuffer.buffer.asUint8List();
+    doubleBufferUint8[0] = readByte();
+    doubleBufferUint8[1] = readByte();
+    doubleBufferUint8[2] = readByte();
+    doubleBufferUint8[3] = readByte();
+    doubleBufferUint8[4] = readByte();
+    doubleBufferUint8[5] = readByte();
+    doubleBufferUint8[6] = readByte();
+    doubleBufferUint8[7] = readByte();
     return _doubleBuffer[0];
   }
 
@@ -244,7 +257,7 @@
   String readStringEntry(int numBytes) {
     String string = _readStringEntry(numBytes);
     if (stringInterner == null) return string;
-    return stringInterner.internString(string);
+    return stringInterner!.internString(string);
   }
 
   String _readStringEntry(int numBytes) {
@@ -309,7 +322,7 @@
   }
 
   /// Reads metadata for the given [node].
-  Node _associateMetadata(Node node, int nodeOffset) {
+  T _associateMetadata<T extends Node>(T node, int nodeOffset) {
     // Default reader ignores metadata section entirely.
     return node;
   }
@@ -393,7 +406,7 @@
   }
 
   Constant _readSymbolConstant() {
-    Reference libraryReference = readLibraryReference(allowNull: true);
+    Reference? libraryReference = readNullableLibraryReference();
     return new SymbolConstant(readStringReference(), libraryReference);
   }
 
@@ -423,12 +436,13 @@
   }
 
   Constant _readInstanceConstant() {
-    final Reference classReference = readClassReference();
+    final Reference classReference = readNonNullClassReference();
     final List<DartType> typeArguments = readDartTypeList();
     final int fieldValueCount = readUInt30();
     final Map<Reference, Constant> fieldValues = <Reference, Constant>{};
     for (int i = 0; i < fieldValueCount; i++) {
-      final Reference fieldRef = readCanonicalNameReference().getReference();
+      final Reference fieldRef =
+          readNonNullCanonicalNameReference().getReference();
       final Constant constant = readConstantReference();
       fieldValues[fieldRef] = constant;
     }
@@ -443,7 +457,8 @@
   }
 
   Constant _readTearOffConstant() {
-    final Reference reference = readCanonicalNameReference().getReference();
+    final Reference reference =
+        readNonNullCanonicalNameReference().getReference();
     return new TearOffConstant.byReference(reference);
   }
 
@@ -459,9 +474,9 @@
 
   Constant readConstantReference() {
     final int offset = readUInt30();
-    Constant constant = _constantTable[offset];
-    assert(constant != null);
-    return constant;
+    Constant? constant = _constantTable[offset];
+    assert(constant != null, "No constant found at offset $offset.");
+    return constant!;
   }
 
   List<Constant> _readConstantReferenceList() {
@@ -470,7 +485,7 @@
         growable: useGrowableLists);
   }
 
-  Uri readUriReference() {
+  Uri? readUriReference() {
     return _sourceUriTable[readUInt30()];
   }
 
@@ -484,7 +499,7 @@
         growable: useGrowableLists);
   }
 
-  String readStringOrNullIfEmpty() {
+  String? readStringOrNullIfEmpty() {
     String string = readStringReference();
     return string.isEmpty ? null : string;
   }
@@ -500,7 +515,7 @@
     }
   }
 
-  List<Expression> readAnnotationList(TreeNode parent) {
+  List<Expression> readAnnotationList(TreeNode? parent) {
     int length = readUInt30();
     if (length == 0) return const <Expression>[];
     return new List<Expression>.generate(
@@ -599,9 +614,9 @@
   /// If [createView] is true, returns a list of [SubComponentView] - one for
   /// each concatenated dill - each of which knowing where in the combined dill
   /// it came from. If [createView] is false null will be returned.
-  List<SubComponentView> readComponent(Component component,
+  List<SubComponentView>? readComponent(Component component,
       {bool checkCanonicalNames: false, bool createView: false}) {
-    return Timeline.timeSync<List<SubComponentView>>(
+    return Timeline.timeSync<List<SubComponentView>?>(
         "BinaryBuilder.readComponent", () {
       _checkEmptyInput();
 
@@ -626,16 +641,16 @@
         _disableLazyClassReading = true;
       }
       int componentFileIndex = 0;
-      List<SubComponentView> views;
+      List<SubComponentView>? views;
       if (createView) {
         views = <SubComponentView>[];
       }
       while (_byteOffset < _bytes.length) {
-        SubComponentView view = _readOneComponent(
+        SubComponentView? view = _readOneComponent(
             component, componentFileSizes[componentFileIndex],
             createView: createView);
         if (createView) {
-          views.add(view);
+          views!.add(view!);
         }
         ++componentFileIndex;
       }
@@ -696,7 +711,7 @@
   }
 
   void _checkCanonicalNameChildren(CanonicalName parent) {
-    Iterable<CanonicalName> parentChildren = parent.childrenOrNull;
+    Iterable<CanonicalName>? parentChildren = parent.childrenOrNull;
     if (parentChildren != null) {
       for (CanonicalName child in parentChildren) {
         if (child.name != '@methods' &&
@@ -722,11 +737,11 @@
             }
           }
           if (checkReferenceNode) {
-            if (child.reference.canonicalName != child) {
+            if (child.reference!.canonicalName != child) {
               throw new CanonicalNameError(
                   "Canonical name and reference doesn't agree.");
             }
-            if (child.reference.node == null) {
+            if (child.reference!.node == null) {
               throw buildCanonicalNameError(
                   "Reference is null (${child.name}) ($child).", child);
             }
@@ -741,7 +756,7 @@
       String message, CanonicalName problemNode) {
     // Special-case missing sdk entries as that is probably a change to the
     // platform - that's something we might want to react differently to.
-    String libraryUri = problemNode?.nonRootTop?.name ?? "";
+    String libraryUri = problemNode.nonRootTop?.name ?? "";
     if (libraryUri.startsWith("dart:")) {
       return new CanonicalNameSdkError(message);
     }
@@ -751,48 +766,56 @@
   _ComponentIndex _readComponentIndex(int componentFileSize) {
     int savedByteIndex = _byteOffset;
 
-    _ComponentIndex result = new _ComponentIndex();
-
     // There are two fields: file size and library count.
     _byteOffset = _componentStartOffset + componentFileSize - (2) * 4;
-    result.libraryCount = readUint32();
+    int libraryCount = readUint32();
     // Library offsets are used for start and end offsets, so there is one extra
     // element that this the end offset of the last library
-    result.libraryOffsets = new List<int>.filled(
-        result.libraryCount + 1,
+    List<int> libraryOffsets = new List<int>.filled(
+        libraryCount + 1,
         // Use `-1` as a dummy default value.
         -1,
         growable: false);
-    result.componentFileSizeInBytes = readUint32();
-    if (result.componentFileSizeInBytes != componentFileSize) {
+    int componentFileSizeInBytes = readUint32();
+    if (componentFileSizeInBytes != componentFileSize) {
       throw "Malformed binary: This component file's component index indicates "
           "that the file size should be $componentFileSize but other component "
           "indexes has indicated that the size should be "
-          "${result.componentFileSizeInBytes}.";
+          "${componentFileSizeInBytes}.";
     }
 
     // Skip to the start of the index.
     _byteOffset -=
-        ((result.libraryCount + 1) + _ComponentIndex.numberOfFixedFields) * 4;
+        ((libraryCount + 1) + _ComponentIndex.numberOfFixedFields) * 4;
 
     // Now read the component index.
-    result.binaryOffsetForSourceTable = _componentStartOffset + readUint32();
-    result.binaryOffsetForCanonicalNames = _componentStartOffset + readUint32();
-    result.binaryOffsetForMetadataPayloads =
-        _componentStartOffset + readUint32();
-    result.binaryOffsetForMetadataMappings =
-        _componentStartOffset + readUint32();
-    result.binaryOffsetForStringTable = _componentStartOffset + readUint32();
-    result.binaryOffsetForConstantTable = _componentStartOffset + readUint32();
-    result.mainMethodReference = readUint32();
-    result.compiledMode = NonNullableByDefaultCompiledMode.values[readUint32()];
-    for (int i = 0; i < result.libraryCount + 1; ++i) {
-      result.libraryOffsets[i] = _componentStartOffset + readUint32();
+    int binaryOffsetForSourceTable = _componentStartOffset + readUint32();
+    int binaryOffsetForCanonicalNames = _componentStartOffset + readUint32();
+    int binaryOffsetForMetadataPayloads = _componentStartOffset + readUint32();
+    int binaryOffsetForMetadataMappings = _componentStartOffset + readUint32();
+    int binaryOffsetForStringTable = _componentStartOffset + readUint32();
+    int binaryOffsetForConstantTable = _componentStartOffset + readUint32();
+    int mainMethodReference = readUint32();
+    NonNullableByDefaultCompiledMode compiledMode =
+        NonNullableByDefaultCompiledMode.values[readUint32()];
+    for (int i = 0; i < libraryCount + 1; ++i) {
+      libraryOffsets[i] = _componentStartOffset + readUint32();
     }
 
     _byteOffset = savedByteIndex;
 
-    return result;
+    return new _ComponentIndex(
+        libraryCount: libraryCount,
+        libraryOffsets: libraryOffsets,
+        componentFileSizeInBytes: componentFileSizeInBytes,
+        binaryOffsetForSourceTable: binaryOffsetForSourceTable,
+        binaryOffsetForCanonicalNames: binaryOffsetForCanonicalNames,
+        binaryOffsetForMetadataPayloads: binaryOffsetForMetadataPayloads,
+        binaryOffsetForMetadataMappings: binaryOffsetForMetadataMappings,
+        binaryOffsetForStringTable: binaryOffsetForStringTable,
+        binaryOffsetForConstantTable: binaryOffsetForConstantTable,
+        mainMethodReference: mainMethodReference,
+        compiledMode: compiledMode);
   }
 
   void _readOneComponentSource(Component component, int componentFileSize) {
@@ -814,13 +837,14 @@
     _ComponentIndex index = _readComponentIndex(componentFileSize);
 
     _byteOffset = index.binaryOffsetForSourceTable;
-    Map<Uri, Source> uriToSource = readUriToSource(/* readCoverage = */ false);
+    Map<Uri?, Source> uriToSource = readUriToSource(readCoverage: false);
     _mergeUriToSource(component.uriToSource, uriToSource);
 
     _byteOffset = _componentStartOffset + componentFileSize;
   }
 
-  SubComponentView _readOneComponent(Component component, int componentFileSize,
+  SubComponentView? _readOneComponent(
+      Component component, int componentFileSize,
       {bool createView: false}) {
     _componentStartOffset = _byteOffset;
 
@@ -836,10 +860,10 @@
 
     _readAndVerifySdkHash();
 
-    List<String> problemsAsJson = readListOfStrings();
+    List<String>? problemsAsJson = readListOfStrings();
     if (problemsAsJson != null) {
       component.problemsAsJson ??= <String>[];
-      component.problemsAsJson.addAll(problemsAsJson);
+      component.problemsAsJson!.addAll(problemsAsJson);
     }
 
     // Read component index from the end of this ComponentFiles serialized data.
@@ -863,7 +887,7 @@
     _associateMetadata(component, _componentStartOffset);
 
     _byteOffset = index.binaryOffsetForSourceTable;
-    Map<Uri, Source> uriToSource = readUriToSource(/* readCoverage = */ true);
+    Map<Uri?, Source> uriToSource = readUriToSource(readCoverage: true);
     _mergeUriToSource(component.uriToSource, uriToSource);
 
     _byteOffset = index.binaryOffsetForConstantTable;
@@ -871,7 +895,7 @@
 
     int numberOfLibraries = index.libraryCount;
 
-    SubComponentView result;
+    SubComponentView? result;
     if (createView) {
       result = new SubComponentView(
           new List<Library>.generate(numberOfLibraries, (int i) {
@@ -887,9 +911,9 @@
       }
     }
 
-    Reference mainMethod =
-        getMemberReferenceFromInt(index.mainMethodReference, allowNull: true);
-    component.setMainMethodAndMode(mainMethod, false, compilationMode);
+    Reference? mainMethod =
+        getNullableMemberReferenceFromInt(index.mainMethodReference);
+    component.setMainMethodAndMode(mainMethod, false, compilationMode!);
 
     _byteOffset = _componentStartOffset + componentFileSize;
 
@@ -899,7 +923,7 @@
   }
 
   /// Read a list of strings. If the list is empty, [null] is returned.
-  List<String> readListOfStrings() {
+  List<String>? readListOfStrings() {
     int length = readUInt30();
     if (length == 0) return null;
     return new List<String>.generate(length, (_) => readString(),
@@ -911,17 +935,18 @@
   /// [readCoverage] is true, otherwise coverage will be skipped. Note also that
   /// if [readCoverage] is true, references are read and that the link table
   /// thus has to be read first.
-  Map<Uri, Source> readUriToSource(bool readCoverage) {
+  Map<Uri?, Source> readUriToSource({required bool readCoverage}) {
+    // ignore: unnecessary_null_comparison
     assert(!readCoverage || (readCoverage && _linkTable != null));
 
     int length = readUint32();
 
     // Read data.
     _sourceUriTable.length = length;
-    Map<Uri, Source> uriToSource = <Uri, Source>{};
+    Map<Uri?, Source> uriToSource = <Uri, Source>{};
     for (int i = 0; i < length; ++i) {
       String uriString = readString();
-      Uri uri = uriString.isEmpty ? null : Uri.parse(uriString);
+      Uri? uri = uriString.isEmpty ? null : Uri.parse(uriString);
       _sourceUriTable[i] = uri;
       Uint8List sourceCode = readByteList();
       int lineCount = readUInt30();
@@ -937,21 +962,22 @@
         previousLineStart = lineStart;
       }
       String importUriString = readString();
-      Uri importUri =
+      Uri? importUri =
           importUriString.isEmpty ? null : Uri.parse(importUriString);
 
-      Set<Reference> coverageConstructors;
+      Set<Reference>? coverageConstructors;
       {
         int constructorCoverageCount = readUInt30();
-        if (readCoverage) {
-          coverageConstructors =
-              constructorCoverageCount == 0 ? null : new Set<Reference>();
-          for (int j = 0; j < constructorCoverageCount; ++j) {
-            coverageConstructors.add(readMemberReference());
-          }
-        } else {
-          for (int j = 0; j < constructorCoverageCount; ++j) {
-            skipMemberReference();
+        if (constructorCoverageCount > 0) {
+          if (readCoverage) {
+            coverageConstructors = new Set<Reference>();
+            for (int j = 0; j < constructorCoverageCount; ++j) {
+              coverageConstructors.add(readNonNullMemberReference());
+            }
+          } else {
+            for (int j = 0; j < constructorCoverageCount; ++j) {
+              skipMemberReference();
+            }
           }
         }
       }
@@ -971,14 +997,14 @@
   // source with an empty source. Empty sources may be introduced by
   // synthetic, copy-down implementations such as mixin applications or
   // noSuchMethod forwarders.
-  void _mergeUriToSource(Map<Uri, Source> dst, Map<Uri, Source> src) {
+  void _mergeUriToSource(Map<Uri?, Source> dst, Map<Uri?, Source> src) {
     if (dst.isEmpty) {
       // Fast path for the common case of one component per binary.
       dst.addAll(src);
     } else {
-      src.forEach((Uri key, Source value) {
-        Source originalDestinationSource = dst[key];
-        Source mergeFrom;
+      src.forEach((Uri? key, Source value) {
+        Source? originalDestinationSource = dst[key];
+        Source? mergeFrom;
         Source mergeTo;
         if (value.source.isNotEmpty || originalDestinationSource == null) {
           dst[key] = value;
@@ -1000,9 +1026,9 @@
         } else if (mergeFrom?.constantCoverageConstructors == null) {
           // Nothing to do.
         } else {
-          // Bot are non-null: Merge.
-          mergeTo.constantCoverageConstructors
-              .addAll(mergeFrom.constantCoverageConstructors);
+          // Both are non-null: Merge.
+          mergeTo.constantCoverageConstructors!
+              .addAll(mergeFrom!.constantCoverageConstructors!);
         }
       });
     }
@@ -1012,71 +1038,99 @@
     readUInt30();
   }
 
-  CanonicalName readCanonicalNameReference() {
+  CanonicalName? readNullableCanonicalNameReference() {
     int index = readUInt30();
     if (index == 0) return null;
     return _linkTable[index - 1];
   }
 
-  CanonicalName getCanonicalNameReferenceFromInt(int index) {
+  CanonicalName readNonNullCanonicalNameReference() {
+    CanonicalName? canonicalName = readNullableCanonicalNameReference();
+    if (canonicalName == null) {
+      throw new StateError('No canonical name found.');
+    }
+    return canonicalName;
+  }
+
+  CanonicalName? getNullableCanonicalNameReferenceFromInt(int index) {
     if (index == 0) return null;
     return _linkTable[index - 1];
   }
 
-  Reference readLibraryReference({bool allowNull: false}) {
-    CanonicalName canonicalName = readCanonicalNameReference();
+  Reference? readNullableLibraryReference() {
+    CanonicalName? canonicalName = readNullableCanonicalNameReference();
+    return canonicalName?.getReference();
+  }
+
+  Reference readNonNullLibraryReference() {
+    CanonicalName? canonicalName = readNullableCanonicalNameReference();
     if (canonicalName != null) return canonicalName.getReference();
-    if (allowNull) return null;
     throw 'Expected a library reference to be valid but was `null`.';
   }
 
   LibraryDependency readLibraryDependencyReference() {
     int index = readUInt30();
-    return _currentLibrary.dependencies[index];
+    return _currentLibrary!.dependencies[index];
   }
 
-  Reference readClassReference({bool allowNull: false}) {
-    CanonicalName name = readCanonicalNameReference();
-    if (name == null && !allowNull) {
+  Reference? readNullableClassReference() {
+    CanonicalName? name = readNullableCanonicalNameReference();
+    return name?.getReference();
+  }
+
+  Reference readNonNullClassReference() {
+    CanonicalName? name = readNullableCanonicalNameReference();
+    if (name == null) {
       throw 'Expected a class reference to be valid but was `null`.';
     }
-    return name?.getReference();
+    return name.getReference();
   }
 
   void skipMemberReference() {
     skipCanonicalNameReference();
   }
 
-  Reference readMemberReference({bool allowNull: false}) {
-    CanonicalName name = readCanonicalNameReference();
-    if (name == null && !allowNull) {
-      throw 'Expected a member reference to be valid but was `null`.';
-    }
+  Reference? readNullableMemberReference() {
+    CanonicalName? name = readNullableCanonicalNameReference();
     return name?.getReference();
   }
 
-  Reference readInstanceMemberReference({bool allowNull: false}) {
-    Reference reference = readMemberReference(allowNull: allowNull);
-    readMemberReference(allowNull: true); // Skip origin
+  Reference readNonNullMemberReference() {
+    CanonicalName? name = readNullableCanonicalNameReference();
+    if (name == null) {
+      throw 'Expected a member reference to be valid but was `null`.';
+    }
+    return name.getReference();
+  }
+
+  Reference? readNullableInstanceMemberReference() {
+    Reference? reference = readNullableMemberReference();
+    readNullableMemberReference(); // Skip origin
     return reference;
   }
 
-  Reference getMemberReferenceFromInt(int index, {bool allowNull: false}) {
-    CanonicalName name = getCanonicalNameReferenceFromInt(index);
-    if (name == null && !allowNull) {
-      throw 'Expected a member reference to be valid but was `null`.';
-    }
-    return name?.getReference();
+  Reference readNonNullInstanceMemberReference() {
+    Reference reference = readNonNullMemberReference();
+    readNullableMemberReference(); // Skip origin
+    return reference;
   }
 
-  Reference readTypedefReference() {
-    return readCanonicalNameReference()?.getReference();
+  Reference? getNullableMemberReferenceFromInt(int index) {
+    return getNullableCanonicalNameReferenceFromInt(index)?.getReference();
+  }
+
+  Reference? readNullableTypedefReference() {
+    return readNullableCanonicalNameReference()?.getReference();
+  }
+
+  Reference readNonNullTypedefReference() {
+    return readNonNullCanonicalNameReference().getReference();
   }
 
   Name readName() {
     String text = readStringReference();
     if (text.isNotEmpty && text[0] == '_') {
-      return new Name.byReference(text, readLibraryReference());
+      return new Name.byReference(text, readNonNullLibraryReference());
     } else {
       return new Name(text);
     }
@@ -1122,9 +1176,9 @@
     int languageVersionMajor = readUInt30();
     int languageVersionMinor = readUInt30();
 
-    CanonicalName canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readNonNullCanonicalNameReference();
     Reference reference = canonicalName.getReference();
-    Library library = reference.node;
+    Library? library = reference.node as Library?;
     if (alwaysCreateNewNamedNodes) {
       library = null;
     }
@@ -1134,12 +1188,12 @@
       component.libraries.add(library..parent = component);
     }
     _currentLibrary = library;
-    String name = readStringOrNullIfEmpty();
+    String? name = readStringOrNullIfEmpty();
 
     // TODO(jensj): We currently save (almost the same) uri twice.
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
 
-    List<String> problemsAsJson = readListOfStrings();
+    List<String>? problemsAsJson = readListOfStrings();
 
     library.flags = flags;
     library.setLanguageVersion(
@@ -1156,7 +1210,7 @@
         "into component with mode $compilationMode");
 
     assert(() {
-      debugPath.add(library.name ?? library.importUri?.toString() ?? 'library');
+      debugPath.add(library!.name ?? library.importUri.toString());
       return true;
     }());
 
@@ -1201,8 +1255,8 @@
     int fileOffset = readOffset();
     int flags = readByte();
     List<Expression> annotations = readExpressionList();
-    Reference targetLibrary = readLibraryReference(allowNull: true);
-    String prefixName = readStringOrNullIfEmpty();
+    Reference targetLibrary = readNonNullLibraryReference();
+    String? prefixName = readStringOrNullIfEmpty();
     List<Combinator> names = readCombinatorList();
     return new LibraryDependency.byReference(
         flags, annotations, targetLibrary, prefixName, names)
@@ -1215,7 +1269,7 @@
     if (numExportedReference != 0) {
       library.additionalExports.clear();
       for (int i = 0; i < numExportedReference; i++) {
-        CanonicalName exportedName = readCanonicalNameReference();
+        CanonicalName exportedName = readNonNullCanonicalNameReference();
         Reference reference = exportedName.getReference();
         library.additionalExports.add(reference);
       }
@@ -1254,18 +1308,18 @@
   }
 
   Typedef readTypedef() {
-    CanonicalName canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readNonNullCanonicalNameReference();
     Reference reference = canonicalName.getReference();
-    Typedef node = reference.node;
+    Typedef? node = reference.node as Typedef?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
-    if (node == null) {
-      node = new Typedef(null, null, reference: reference);
-    }
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
     int fileOffset = readOffset();
     String name = readStringReference();
+    if (node == null) {
+      node = new Typedef(name, null, reference: reference);
+    }
     node.annotations = readAnnotationList(node);
     readAndPushTypeParameterList(node.typeParameters, node);
     DartType type = readDartType();
@@ -1302,13 +1356,13 @@
         growable: false);
     _byteOffset = savedByteOffset;
 
-    CanonicalName canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readNonNullCanonicalNameReference();
     Reference reference = canonicalName.getReference();
-    Class node = reference.node;
+    Class? node = reference.node as Class?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
     int startFileOffset = readOffset();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
@@ -1324,15 +1378,15 @@
     node.flags = flags;
     List<Expression> annotations = readAnnotationList(node);
     assert(() {
-      debugPath.add(node.name ?? 'normal-class');
+      debugPath.add(name);
       return true;
     }());
 
     assert(typeParameterStack.length == 0);
 
     readAndPushTypeParameterList(node.typeParameters, node);
-    Supertype supertype = readSupertypeOption();
-    Supertype mixedInType = readSupertypeOption();
+    Supertype? supertype = readSupertypeOption();
+    Supertype? mixedInType = readSupertypeOption();
     _fillNonTreeNodeList(node.implementedTypes, readSupertype);
     if (_disableLazyClassReading) {
       readClassPartialContent(node, procedureOffsets);
@@ -1341,6 +1395,7 @@
     }
 
     typeParameterStack.length = 0;
+    // ignore: unnecessary_null_comparison
     assert(debugPath.removeLast() != null);
     node.name = name;
     node.fileUri = fileUri;
@@ -1357,9 +1412,9 @@
     int tag = readByte();
     assert(tag == Tag.Extension);
 
-    CanonicalName canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readNonNullCanonicalNameReference();
     Reference reference = canonicalName.getReference();
-    Extension node = reference.node;
+    Extension? node = reference.node as Extension?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
@@ -1373,7 +1428,7 @@
       return true;
     }());
 
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
     node.fileOffset = readOffset();
 
     readAndPushTypeParameterList(node.typeParameters, node);
@@ -1390,7 +1445,7 @@
       Name name = readName();
       int kind = readByte();
       int flags = readByte();
-      CanonicalName canonicalName = readCanonicalNameReference();
+      CanonicalName canonicalName = readNonNullCanonicalNameReference();
       node.members[i] = new ExtensionMemberDescriptor(
           name: name,
           kind: ExtensionMemberKind.values[kind],
@@ -1420,7 +1475,7 @@
   void _setLazyLoadClass(Class node, List<int> procedureOffsets) {
     final int savedByteOffset = _byteOffset;
     final int componentStartOffset = _componentStartOffset;
-    final Library currentLibrary = _currentLibrary;
+    final Library? currentLibrary = _currentLibrary;
     node.lazyBuilder = () {
       _byteOffset = savedByteOffset;
       _currentLibrary = currentLibrary;
@@ -1447,11 +1502,11 @@
   Field readField() {
     int tag = readByte();
     assert(tag == Tag.Field);
-    CanonicalName getterCanonicalName = readCanonicalNameReference();
+    CanonicalName getterCanonicalName = readNonNullCanonicalNameReference();
     Reference getterReference = getterCanonicalName.getReference();
-    CanonicalName setterCanonicalName = readCanonicalNameReference();
-    Reference setterReference = setterCanonicalName?.getReference();
-    Field node = getterReference.node;
+    CanonicalName? setterCanonicalName = readNullableCanonicalNameReference();
+    Reference? setterReference = setterCanonicalName?.getReference();
+    Field? node = getterReference.node as Field?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
@@ -1463,18 +1518,18 @@
         node = new Field.immutable(null, getterReference: getterReference);
       }
     }
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
     int flags = readUInt30();
     Name name = readName();
     List<Expression> annotations = readAnnotationList(node);
     assert(() {
-      debugPath.add(node.name?.text ?? 'field');
+      debugPath.add(name.text);
       return true;
     }());
     DartType type = readDartType();
-    Expression initializer = readExpressionOption();
+    Expression? initializer = readExpressionOption();
     int transformerFlags = getAndResetTransformerFlags();
     assert(((_) => true)(debugPath.removeLast()));
     node.fileOffset = fileOffset;
@@ -1493,16 +1548,16 @@
   Constructor readConstructor() {
     int tag = readByte();
     assert(tag == Tag.Constructor);
-    CanonicalName canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readNonNullCanonicalNameReference();
     Reference reference = canonicalName.getReference();
-    Constructor node = reference.node;
+    Constructor? node = reference.node as Constructor?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
     if (node == null) {
       node = new Constructor(null, reference: reference);
     }
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
     int startFileOffset = readOffset();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
@@ -1510,7 +1565,7 @@
     Name name = readName();
     List<Expression> annotations = readAnnotationList(node);
     assert(() {
-      debugPath.add(node.name?.text ?? 'constructor');
+      debugPath.add(name.text);
       return true;
     }());
     FunctionNode function = readFunctionNode();
@@ -1535,13 +1590,13 @@
   Procedure readProcedure(int endOffset) {
     int tag = readByte();
     assert(tag == Tag.Procedure);
-    CanonicalName canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readNonNullCanonicalNameReference();
     Reference reference = canonicalName.getReference();
-    Procedure node = reference.node;
+    Procedure? node = reference.node as Procedure?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
     int startFileOffset = readOffset();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
@@ -1557,7 +1612,7 @@
     Name name = readName();
     List<Expression> annotations = readAnnotationList(node);
     assert(() {
-      debugPath.add(node.name?.text ?? 'procedure');
+      debugPath.add(name.text);
       return true;
     }());
     int functionNodeSize = endOffset - _byteOffset;
@@ -1565,8 +1620,8 @@
     bool readFunctionNodeNow =
         (kind == ProcedureKind.Factory && functionNodeSize <= 50) ||
             _disableLazyReading;
-    Reference stubTargetReference = readMemberReference(allowNull: true);
-    FunctionNode function =
+    Reference? stubTargetReference = readNullableMemberReference();
+    FunctionNode? function =
         readFunctionNodeOption(!readFunctionNodeNow, endOffset);
     int transformerFlags = getAndResetTransformerFlags();
     assert(((_) => true)(debugPath.removeLast()));
@@ -1585,7 +1640,7 @@
 
     assert((node.stubKind == ProcedureStubKind.ConcreteForwardingStub &&
             node.stubTargetReference != null) ||
-        !(node.isForwardingStub && node.function.body != null));
+        !(node.isForwardingStub && node.function!.body != null));
     assert(!(node.isMemberSignature && node.stubTargetReference == null),
         "No member signature origin for member signature $node.");
     return node;
@@ -1594,26 +1649,27 @@
   RedirectingFactoryConstructor readRedirectingFactoryConstructor() {
     int tag = readByte();
     assert(tag == Tag.RedirectingFactoryConstructor);
-    CanonicalName canonicalName = readCanonicalNameReference();
+    CanonicalName canonicalName = readNonNullCanonicalNameReference();
     Reference reference = canonicalName.getReference();
-    RedirectingFactoryConstructor node = reference.node;
+    RedirectingFactoryConstructor? node =
+        reference.node as RedirectingFactoryConstructor?;
     if (alwaysCreateNewNamedNodes) {
       node = null;
     }
     if (node == null) {
       node = new RedirectingFactoryConstructor(null, reference: reference);
     }
-    Uri fileUri = readUriReference();
+    Uri? fileUri = readUriReference();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
     int flags = readByte();
     Name name = readName();
     List<Expression> annotations = readAnnotationList(node);
     assert(() {
-      debugPath.add(node.name?.text ?? 'redirecting-factory-constructor');
+      debugPath.add(name.text);
       return true;
     }());
-    Reference targetReference = readMemberReference();
+    Reference targetReference = readNonNullMemberReference();
     List<DartType> typeArguments = readDartTypeList();
     int typeParameterStackHeight = typeParameterStack.length;
     List<TypeParameter> typeParameters = readAndPushTypeParameterList();
@@ -1666,7 +1722,7 @@
   }
 
   Initializer _readFieldInitializer(bool isSynthetic) {
-    Reference reference = readMemberReference();
+    Reference reference = readNonNullMemberReference();
     Expression value = readExpression();
     return new FieldInitializer.byReference(reference, value)
       ..isSynthetic = isSynthetic;
@@ -1674,7 +1730,7 @@
 
   Initializer _readSuperInitializer(bool isSynthetic) {
     int offset = readOffset();
-    Reference reference = readMemberReference();
+    Reference reference = readNonNullMemberReference();
     Arguments arguments = readArguments();
     return new SuperInitializer.byReference(reference, arguments)
       ..isSynthetic = isSynthetic
@@ -1684,7 +1740,7 @@
   Initializer _readRedirectingInitializer() {
     int offset = readOffset();
     return new RedirectingInitializer.byReference(
-        readMemberReference(), readArguments())
+        readNonNullMemberReference(), readArguments())
       ..fileOffset = offset;
   }
 
@@ -1693,10 +1749,10 @@
   }
 
   Initializer _readAssertInitializer() {
-    return new AssertInitializer(readStatement());
+    return new AssertInitializer(readStatement() as AssertStatement);
   }
 
-  FunctionNode readFunctionNodeOption(bool lazyLoadBody, int outerEndOffset) {
+  FunctionNode? readFunctionNodeOption(bool lazyLoadBody, int outerEndOffset) {
     return readAndCheckOptionTag()
         ? readFunctionNode(
             lazyLoadBody: lazyLoadBody, outerEndOffset: outerEndOffset)
@@ -1719,7 +1775,7 @@
     List<VariableDeclaration> positional = readAndPushVariableDeclarationList();
     List<VariableDeclaration> named = readAndPushVariableDeclarationList();
     DartType returnType = readDartType();
-    DartType futureValueType = readDartTypeOption();
+    DartType? futureValueType = readDartTypeOption();
     int oldLabelStackBase = labelStackBase;
     int oldSwitchCaseStackBase = switchCaseStackBase;
 
@@ -1728,7 +1784,7 @@
           2; // e.g. outline has Tag.Something and Tag.EmptyStatement
     }
 
-    Statement body;
+    Statement? body;
     if (!lazyLoadBody) {
       labelStackBase = labelStack.length;
       switchCaseStackBase = switchCaseStack.length;
@@ -1766,7 +1822,7 @@
     final int componentStartOffset = _componentStartOffset;
     final List<TypeParameter> typeParameters = typeParameterStack.toList();
     final List<VariableDeclaration> variables = variableStack.toList();
-    final Library currentLibrary = _currentLibrary;
+    final Library currentLibrary = _currentLibrary!;
     result.lazyBuilder = () {
       _byteOffset = savedByteOffset;
       _currentLibrary = currentLibrary;
@@ -1782,8 +1838,8 @@
       switchCaseStackBase = oldSwitchCaseStackBase;
       variableStack.length = variableStackHeight;
       typeParameterStack.clear();
-      if (result.parent is Procedure) {
-        Procedure parent = result.parent;
+      TreeNode? parent = result.parent;
+      if (parent is Procedure) {
         parent.transformerFlags |= getAndResetTransformerFlags();
       }
     };
@@ -1828,7 +1884,7 @@
         growable: useGrowableLists);
   }
 
-  Expression readExpressionOption() {
+  Expression? readExpressionOption() {
     return readAndCheckOptionTag() ? readExpression() : null;
   }
 
@@ -2028,8 +2084,8 @@
 
   Expression _readPropertyGet() {
     int offset = readOffset();
-    return new PropertyGet.byReference(readExpression(), readName(),
-        readInstanceMemberReference(allowNull: true))
+    return new PropertyGet.byReference(
+        readExpression(), readName(), readNullableInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2038,7 +2094,7 @@
     int offset = readOffset();
     return new InstanceGet.byReference(kind, readExpression(), readName(),
         resultType: readDartType(),
-        interfaceTargetReference: readInstanceMemberReference())
+        interfaceTargetReference: readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2047,7 +2103,7 @@
     int offset = readOffset();
     return new InstanceTearOff.byReference(kind, readExpression(), readName(),
         resultType: readDartType(),
-        interfaceTargetReference: readInstanceMemberReference())
+        interfaceTargetReference: readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2061,7 +2117,7 @@
   Expression _readPropertySet() {
     int offset = readOffset();
     return new PropertySet.byReference(readExpression(), readName(),
-        readExpression(), readInstanceMemberReference(allowNull: true))
+        readExpression(), readNullableInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2070,7 +2126,7 @@
     int offset = readOffset();
     return new InstanceSet.byReference(
         kind, readExpression(), readName(), readExpression(),
-        interfaceTargetReference: readInstanceMemberReference())
+        interfaceTargetReference: readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
@@ -2085,33 +2141,34 @@
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
     return new SuperPropertyGet.byReference(
-        readName(), readInstanceMemberReference(allowNull: true))
+        readName(), readNullableInstanceMemberReference())
       ..fileOffset = offset;
   }
 
   Expression _readSuperPropertySet() {
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
-    return new SuperPropertySet.byReference(readName(), readExpression(),
-        readInstanceMemberReference(allowNull: true))
+    return new SuperPropertySet.byReference(
+        readName(), readExpression(), readNullableInstanceMemberReference())
       ..fileOffset = offset;
   }
 
   Expression _readStaticGet() {
     int offset = readOffset();
-    return new StaticGet.byReference(readMemberReference())
+    return new StaticGet.byReference(readNonNullMemberReference())
       ..fileOffset = offset;
   }
 
   Expression _readStaticTearOff() {
     int offset = readOffset();
-    return new StaticTearOff.byReference(readMemberReference())
+    return new StaticTearOff.byReference(readNonNullMemberReference())
       ..fileOffset = offset;
   }
 
   Expression _readStaticSet() {
     int offset = readOffset();
-    return new StaticSet.byReference(readMemberReference(), readExpression())
+    return new StaticSet.byReference(
+        readNonNullMemberReference(), readExpression())
       ..fileOffset = offset;
   }
 
@@ -2119,7 +2176,7 @@
     int flags = readByte();
     int offset = readOffset();
     return new MethodInvocation.byReference(readExpression(), readName(),
-        readArguments(), readInstanceMemberReference(allowNull: true))
+        readArguments(), readNullableInstanceMemberReference())
       ..fileOffset = offset
       ..flags = flags;
   }
@@ -2130,8 +2187,8 @@
     int offset = readOffset();
     return new InstanceInvocation.byReference(
         kind, readExpression(), readName(), readArguments(),
-        functionType: readDartType(),
-        interfaceTargetReference: readInstanceMemberReference())
+        functionType: readDartType() as FunctionType,
+        interfaceTargetReference: readNonNullInstanceMemberReference())
       ..fileOffset = offset
       ..flags = flags;
   }
@@ -2167,7 +2224,7 @@
     int offset = readOffset();
     readUInt30(); // offset of the variable declaration in the binary.
     return new LocalFunctionInvocation(readVariableReference(), readArguments(),
-        functionType: readDartType())
+        functionType: readDartType() as FunctionType)
       ..fileOffset = offset;
   }
 
@@ -2181,23 +2238,23 @@
     int offset = readOffset();
     return new EqualsCall.byReference(readExpression(), readExpression(),
         isNot: readByte() == 1,
-        functionType: readDartType(),
-        interfaceTargetReference: readInstanceMemberReference())
+        functionType: readDartType() as FunctionType,
+        interfaceTargetReference: readNonNullInstanceMemberReference())
       ..fileOffset = offset;
   }
 
   Expression _readSuperMethodInvocation() {
     int offset = readOffset();
     addTransformerFlag(TransformerFlag.superCalls);
-    return new SuperMethodInvocation.byReference(readName(), readArguments(),
-        readInstanceMemberReference(allowNull: true))
+    return new SuperMethodInvocation.byReference(
+        readName(), readArguments(), readNullableInstanceMemberReference())
       ..fileOffset = offset;
   }
 
   Expression _readStaticInvocation() {
     int offset = readOffset();
     return new StaticInvocation.byReference(
-        readMemberReference(), readArguments(),
+        readNonNullMemberReference(), readArguments(),
         isConst: false)
       ..fileOffset = offset;
   }
@@ -2205,7 +2262,7 @@
   Expression _readConstStaticInvocation() {
     int offset = readOffset();
     return new StaticInvocation.byReference(
-        readMemberReference(), readArguments(),
+        readNonNullMemberReference(), readArguments(),
         isConst: true)
       ..fileOffset = offset;
   }
@@ -2213,7 +2270,7 @@
   Expression _readConstructorInvocation() {
     int offset = readOffset();
     return new ConstructorInvocation.byReference(
-        readMemberReference(), readArguments(),
+        readNonNullMemberReference(), readArguments(),
         isConst: false)
       ..fileOffset = offset;
   }
@@ -2221,7 +2278,7 @@
   Expression _readConstConstructorInvocation() {
     int offset = readOffset();
     return new ConstructorInvocation.byReference(
-        readMemberReference(), readArguments(),
+        readNonNullMemberReference(), readArguments(),
         isConst: true)
       ..fileOffset = offset;
   }
@@ -2241,8 +2298,12 @@
   }
 
   Expression _readConditionalExpression() {
-    return new ConditionalExpression(readExpression(), readExpression(),
-        readExpression(), readDartTypeOption());
+    return new ConditionalExpression(
+        readExpression(),
+        readExpression(),
+        readExpression(),
+        // TODO(johnniwinther): Change this to use `readDartType`.
+        readDartTypeOption()!);
   }
 
   Expression _readStringConcatenation() {
@@ -2277,12 +2338,13 @@
 
   Expression _readInstanceCreation() {
     int offset = readOffset();
-    Reference classReference = readClassReference();
+    Reference classReference = readNonNullClassReference();
     List<DartType> typeArguments = readDartTypeList();
     int fieldValueCount = readUInt30();
     Map<Reference, Expression> fieldValues = <Reference, Expression>{};
     for (int i = 0; i < fieldValueCount; i++) {
-      final Reference fieldRef = readCanonicalNameReference().getReference();
+      final Reference fieldRef =
+          readNonNullCanonicalNameReference().getReference();
       final Expression value = readExpression();
       fieldValues[fieldRef] = value;
     }
@@ -2295,7 +2357,7 @@
       asserts = emptyListOfAssertStatement;
     } else {
       asserts = new List<AssertStatement>.generate(
-          assertCount, (_) => readStatement(),
+          assertCount, (_) => readStatement() as AssertStatement,
           growable: false);
     }
     List<Expression> unusedArguments = readExpressionList();
@@ -2305,7 +2367,7 @@
   }
 
   Expression _readFileUriExpression() {
-    Uri fileUri = readUriReference();
+    Uri fileUri = readUriReference()!;
     int offset = readOffset();
     return new FileUriExpression(readExpression(), fileUri)
       ..fileOffset = offset;
@@ -2503,7 +2565,7 @@
         growable: true);
   }
 
-  Statement readStatementOrNullIfEmpty() {
+  Statement? readStatementOrNullIfEmpty() {
     Statement node = readStatement();
     if (node is EmptyStatement) {
       return null;
@@ -2512,7 +2574,7 @@
     }
   }
 
-  Statement readStatementOption() {
+  Statement? readStatementOption() {
     return readAndCheckOptionTag() ? readStatement() : null;
   }
 
@@ -2611,7 +2673,7 @@
     int variableStackHeight = variableStack.length;
     int offset = readOffset();
     List<VariableDeclaration> variables = readAndPushVariableDeclarationList();
-    Expression condition = readExpressionOption();
+    Expression? condition = readExpressionOption();
     List<Expression> updates = readExpressionList();
     Statement body = readStatement();
     variableStack.length = variableStackHeight;
@@ -2737,8 +2799,8 @@
     int variableStackHeight = variableStack.length;
     int offset = readOffset();
     DartType guard = readDartType();
-    VariableDeclaration exception = readAndPushVariableDeclarationOption();
-    VariableDeclaration stackTrace = readAndPushVariableDeclarationOption();
+    VariableDeclaration? exception = readAndPushVariableDeclarationOption();
+    VariableDeclaration? stackTrace = readAndPushVariableDeclarationOption();
     Statement body = readStatement();
     variableStack.length = variableStackHeight;
     return new Catch(exception, body, guard: guard, stackTrace: stackTrace)
@@ -2764,16 +2826,16 @@
   }
 
   Supertype readSupertype() {
-    InterfaceType type = readDartType(forSupertype: true);
+    InterfaceType type = readDartType(forSupertype: true) as InterfaceType;
     assert(
-        type.nullability == _currentLibrary.nonNullable,
+        type.nullability == _currentLibrary!.nonNullable,
         "In serialized form supertypes should have Nullability.legacy if they "
         "are in a library that is opted out of the NNBD feature.  If they are "
         "in an opted-in library, they should have Nullability.nonNullable.");
     return new Supertype.byReference(type.className, type.typeArguments);
   }
 
-  Supertype readSupertypeOption() {
+  Supertype? readSupertypeOption() {
     return readAndCheckOptionTag() ? readSupertype() : null;
   }
 
@@ -2818,7 +2880,7 @@
         isRequired: (flags & NamedType.FlagRequiredNamedType) != 0);
   }
 
-  DartType readDartTypeOption() {
+  DartType? readDartTypeOption() {
     return readAndCheckOptionTag() ? readDartType() : null;
   }
 
@@ -2852,7 +2914,7 @@
 
   DartType _readTypedefType() {
     int nullabilityIndex = readByte();
-    return new TypedefType.byReference(readTypedefReference(),
+    return new TypedefType.byReference(readNonNullTypedefReference(),
         Nullability.values[nullabilityIndex], readDartTypeList());
   }
 
@@ -2875,14 +2937,14 @@
 
   DartType _readInterfaceType() {
     int nullabilityIndex = readByte();
-    Reference reference = readClassReference();
+    Reference reference = readNonNullClassReference();
     List<DartType> typeArguments = readDartTypeList();
-    CanonicalName canonicalName = reference.canonicalName;
-    if (canonicalName.name == "FutureOr" &&
-        canonicalName.parent != null &&
-        canonicalName.parent.name == "dart:async" &&
-        canonicalName.parent.parent != null &&
-        canonicalName.parent.parent.isRoot) {
+    CanonicalName? canonicalName = reference.canonicalName;
+    if (canonicalName != null &&
+        canonicalName.name == "FutureOr" &&
+        canonicalName.parent!.name == "dart:async" &&
+        canonicalName.parent!.parent != null &&
+        canonicalName.parent!.parent!.isRoot) {
       return new FutureOrType(
           typeArguments.single, Nullability.values[nullabilityIndex]);
     }
@@ -2892,13 +2954,13 @@
 
   DartType _readSimpleInterfaceType(bool forSupertype) {
     int nullabilityIndex = readByte();
-    Reference classReference = readClassReference();
-    CanonicalName canonicalName = classReference.canonicalName;
+    Reference classReference = readNonNullClassReference();
+    CanonicalName? canonicalName = classReference.canonicalName;
     if (canonicalName != null &&
         !forSupertype &&
         canonicalName.name == "Null" &&
-        canonicalName.parent?.name == "dart:core" &&
-        (canonicalName.parent?.parent?.isRoot ?? false)) {
+        canonicalName.parent!.name == "dart:core" &&
+        canonicalName.parent!.parent!.isRoot) {
       return const NullType();
     }
     return new InterfaceType.byReference(classReference,
@@ -2913,7 +2975,7 @@
     int totalParameterCount = readUInt30();
     List<DartType> positional = readDartTypeList();
     List<NamedType> named = readNamedTypeList();
-    DartType typedefType = readDartTypeOption();
+    TypedefType? typedefType = readDartTypeOption() as TypedefType?;
     assert(positional.length + named.length == totalParameterCount);
     DartType returnType = readDartType();
     typeParameterStack.length = typeParameterStackHeight;
@@ -2936,13 +2998,13 @@
   DartType _readTypeParameterType() {
     int declaredNullabilityIndex = readByte();
     int index = readUInt30();
-    DartType bound = readDartTypeOption();
+    DartType? bound = readDartTypeOption();
     return new TypeParameterType(typeParameterStack[index],
         Nullability.values[declaredNullabilityIndex], bound);
   }
 
   List<TypeParameter> readAndPushTypeParameterList(
-      [List<TypeParameter> list, TreeNode parent]) {
+      [List<TypeParameter>? list, TreeNode? parent]) {
     int length = readUInt30();
     if (length == 0) {
       if (list != null) return list;
@@ -3020,7 +3082,7 @@
         growable: useGrowableLists);
   }
 
-  VariableDeclaration readAndPushVariableDeclarationOption() {
+  VariableDeclaration? readAndPushVariableDeclarationOption() {
     return readAndCheckOptionTag() ? readAndPushVariableDeclaration() : null;
   }
 
@@ -3064,13 +3126,13 @@
 class BinaryBuilderWithMetadata extends BinaryBuilder implements BinarySource {
   /// List of metadata subsections that have corresponding [MetadataRepository]
   /// and are awaiting to be parsed and attached to nodes.
-  List<_MetadataSubsection> _subsections;
+  List<_MetadataSubsection>? _subsections;
 
   BinaryBuilderWithMetadata(List<int> bytes,
-      {String filename,
+      {String? filename,
       bool disableLazyReading = false,
       bool disableLazyClassReading = false,
-      bool alwaysCreateNewNamedNodes})
+      bool? alwaysCreateNewNamedNodes})
       : super(bytes,
             filename: filename,
             disableLazyReading: disableLazyReading,
@@ -3098,7 +3160,7 @@
       // UInt32 tag (fixed size StringReference)
       final String tag = _stringTable[readUint32()];
 
-      final MetadataRepository repository = component.metadata[tag];
+      final MetadataRepository<dynamic>? repository = component.metadata[tag];
       if (repository != null) {
         // Read nodeOffsetToMetadataOffset mapping.
         final Map<int, int> mapping = <int, int>{};
@@ -3110,8 +3172,8 @@
           mapping[nodeOffset] = metadataOffset;
         }
 
-        _subsections ??= <_MetadataSubsection>[];
-        _subsections.add(new _MetadataSubsection(repository, mapping));
+        (_subsections ??= <_MetadataSubsection>[])
+            .add(new _MetadataSubsection(repository, mapping));
       }
 
       // Start of the subsection and the end of the previous one.
@@ -3130,28 +3192,28 @@
   }
 
   @override
-  void enterScope({List<TypeParameter> typeParameters}) {
+  void enterScope({List<TypeParameter>? typeParameters}) {
     if (typeParameters != null) {
       typeParameterStack.addAll(typeParameters);
     }
   }
 
   @override
-  void leaveScope({List<TypeParameter> typeParameters}) {
+  void leaveScope({List<TypeParameter>? typeParameters}) {
     if (typeParameters != null) {
       typeParameterStack.length -= typeParameters.length;
     }
   }
 
   @override
-  Node _associateMetadata(Node node, int nodeOffset) {
+  T _associateMetadata<T extends Node>(T node, int nodeOffset) {
     if (_subsections == null) {
       return node;
     }
 
-    for (_MetadataSubsection subsection in _subsections) {
+    for (_MetadataSubsection subsection in _subsections!) {
       // First check if there is any metadata associated with this node.
-      final int metadataOffset = subsection.mapping[nodeOffset];
+      final int? metadataOffset = subsection.mapping[nodeOffset];
       if (metadataOffset != null) {
         subsection.repository.mapping[node] =
             _readMetadata(node, subsection.repository, metadataOffset);
@@ -3312,7 +3374,8 @@
   @override
   Supertype readSupertype() {
     final int nodeOffset = _byteOffset;
-    InterfaceType type = super.readDartType(forSupertype: true);
+    InterfaceType type =
+        super.readDartType(forSupertype: true) as InterfaceType;
     return _associateMetadata(
         new Supertype.byReference(type.className, type.typeArguments),
         nodeOffset);
@@ -3345,7 +3408,7 @@
 
 /// Merges two compilation modes or throws if they are not compatible.
 NonNullableByDefaultCompiledMode mergeCompilationModeOrThrow(
-    NonNullableByDefaultCompiledMode a, NonNullableByDefaultCompiledMode b) {
+    NonNullableByDefaultCompiledMode? a, NonNullableByDefaultCompiledMode b) {
   if (a == null || a == b) {
     return b;
   }
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index 9c8e0a6..bbc745e 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -24,6 +24,9 @@
         return mergeFunctionTypes(a, b, nullability);
       }
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
@@ -146,6 +149,9 @@
         return mergeInterfaceTypes(a, b, nullability);
       }
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
@@ -176,6 +182,9 @@
         return mergeFutureOrTypes(a, b, nullability);
       }
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
@@ -193,6 +202,9 @@
     if (b is DynamicType) {
       return a;
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
@@ -204,6 +216,9 @@
         return NeverType.fromNullability(nullability);
       }
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
@@ -212,17 +227,23 @@
     if (b is NullType) {
       return a;
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
   @override
-  DartType? visitInvalidType(InvalidType a, DartType b) => null;
+  DartType? visitInvalidType(InvalidType a, DartType b) => a;
 
   @override
   DartType? visitVoidType(VoidType a, DartType b) {
     if (b is VoidType) {
       return a;
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
@@ -240,6 +261,9 @@
         return mergeTypeParameterTypes(a, b, nullability);
       }
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
@@ -274,6 +298,9 @@
         return mergeTypedefTypes(a, b, nullability);
       }
     }
+    if (b is InvalidType) {
+      return b;
+    }
     return null;
   }
 
diff --git a/pkg/kernel/lib/src/nnbd_top_merge.dart b/pkg/kernel/lib/src/nnbd_top_merge.dart
index 632ccc3..e709c41 100644
--- a/pkg/kernel/lib/src/nnbd_top_merge.dart
+++ b/pkg/kernel/lib/src/nnbd_top_merge.dart
@@ -90,7 +90,7 @@
       // NNBD_TOP_MERGE(void, Object*) = Object?
       return coreTypes.objectNullableRawType;
     }
-    return null;
+    return super.visitVoidType(a, b);
   }
 
   @override
@@ -108,7 +108,7 @@
       // NNBD_TOP_MERGE(dynamic, Object*) = Object?
       return coreTypes.objectNullableRawType;
     }
-    return null;
+    return super.visitDynamicType(a, b);
   }
 
   @override
diff --git a/pkg/kernel/lib/testing/type_parser.dart b/pkg/kernel/lib/testing/type_parser.dart
index 5842eee..4b935b4e 100644
--- a/pkg/kernel/lib/testing/type_parser.dart
+++ b/pkg/kernel/lib/testing/type_parser.dart
@@ -356,6 +356,9 @@
         type = new ParsedInterfaceType(
             "void", <ParsedType>[], ParsedNullability.nullable);
         optionalAdvance("?");
+      } else if (optionalAdvance("invalid")) {
+        type = new ParsedInterfaceType(
+            "invalid", <ParsedType>[], ParsedNullability.nullable);
       } else {
         String name = parseName();
         List<ParsedType> arguments = <ParsedType>[];
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 937e783..2782dd1 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -13,6 +13,7 @@
         FunctionType,
         FutureOrType,
         InterfaceType,
+        InvalidType,
         Library,
         NamedType,
         NeverType,
@@ -277,6 +278,10 @@
       // Don't return a const object to ensure we test implementations that use
       // identical.
       return new NullType();
+    } else if (name == "invalid") {
+      // Don't return a const object to ensure we test implementations that use
+      // identical.
+      return new InvalidType();
     } else if (additionalTypes != null && additionalTypes.containsKey(name)) {
       return additionalTypes[name].call();
     }
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 844736d..f8ffce6 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1407,9 +1407,8 @@
 
   visitInvalidExpression(InvalidExpression node) {
     writeWord('invalid-expression');
-    // ignore: unnecessary_null_comparison
     if (node.message != null) {
-      writeWord('"${escapeString(node.message)}"');
+      writeWord('"${escapeString(node.message!)}"');
     }
   }
 
@@ -2550,9 +2549,9 @@
     writeIndentation();
     writeConstantReference(node);
     writeSpaced('=');
-    // ignore: unnecessary_null_comparison
-    String text = node.libraryReference != null
-        ? '#${node.libraryReference.asLibrary.importUri}::${node.name}'
+    Reference? libraryReference = node.libraryReference;
+    String text = libraryReference != null
+        ? '#${libraryReference.asLibrary.importUri}::${node.name}'
         : '#${node.name}';
     endLine('${text}');
   }
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 6263d1f..ae54219 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -980,10 +980,11 @@
 ///       @override
 ///       Node visitNot(Not node) {
 ///         var operand = node.operand.accept(this); // Remember to visit.
-///         if (operand is LogicalExpression && operand.operator == '&&') {
+///         if (operand is LogicalExpression &&
+///             operand.operator == LogicalExpressionOperator.AND) {
 ///           return new LogicalExpression(
 ///             new Not(operand.left),
-///             '||',
+///             LogicalExpressionOperator.OR,
 ///             new Not(operand.right));
 ///         }
 ///         return node;
@@ -1109,10 +1110,11 @@
 ///       @override
 ///       Node visitNot(Not node) {
 ///         var operand = node.operand.accept(this); // Remember to visit.
-///         if (operand is LogicalExpression && operand.operator == '&&') {
+///         if (operand is LogicalExpression &&
+///             operand.operator == LogicalExpressionOperator.AND) {
 ///           return new LogicalExpression(
 ///             new Not(operand.left),
-///             '||',
+///             LogicalExpressionOperator.OR,
 ///             new Not(operand.right));
 ///         }
 ///         return node;
diff --git a/pkg/kernel/test/metadata_test.dart b/pkg/kernel/test/metadata_test.dart
index d1214b6..653bdaa 100644
--- a/pkg/kernel/test/metadata_test.dart
+++ b/pkg/kernel/test/metadata_test.dart
@@ -73,7 +73,7 @@
   Metadata readFromBinary(Node node, BinarySource source) {
     final string1 = utf8.decode(source.readByteList());
     final string2 = source.readStringReference();
-    final memberRef = source.readCanonicalNameReference()?.reference;
+    final memberRef = source.readNullableCanonicalNameReference()?.reference;
     final type = source.readDartType();
     expect(string1, equals(string2));
     return new Metadata(string2, memberRef, type);
diff --git a/pkg/kernel/test/nnbd_top_merge_test.dart b/pkg/kernel/test/nnbd_top_merge_test.dart
index 73d07d2..7fac29a 100644
--- a/pkg/kernel/test/nnbd_top_merge_test.dart
+++ b/pkg/kernel/test/nnbd_top_merge_test.dart
@@ -110,6 +110,17 @@
     '<E extends List<E>>(E) -> void',
     '<F extends List<F>>(F) -> void'
   ],
+  'invalid vs invalid': 'invalid',
+  'invalid vs Object': 'invalid',
+  'invalid vs Object?': 'invalid',
+  'Object vs invalid': 'invalid',
+  'Object? vs invalid': 'invalid',
+  'void vs invalid': 'invalid',
+  'dynamic vs invalid': 'invalid',
+  'Null vs invalid': 'invalid',
+  'Never vs invalid': 'invalid',
+  '() -> void vs invalid': 'invalid',
+  '<T>(T) -> void vs <T>(invalid) -> void': '<T>(invalid) -> void',
 };
 
 main() {
diff --git a/pkg/vm/lib/metadata/direct_call.dart b/pkg/vm/lib/metadata/direct_call.dart
index b7e8277..22a26fd 100644
--- a/pkg/vm/lib/metadata/direct_call.dart
+++ b/pkg/vm/lib/metadata/direct_call.dart
@@ -47,7 +47,8 @@
 
   @override
   DirectCallMetadata readFromBinary(Node node, BinarySource source) {
-    final targetReference = source.readCanonicalNameReference()?.getReference();
+    final targetReference =
+        source.readNullableCanonicalNameReference()?.getReference();
     if (targetReference == null) {
       throw 'DirectCallMetadata should have a non-null target';
     }
diff --git a/pkg/vm/lib/metadata/inferred_type.dart b/pkg/vm/lib/metadata/inferred_type.dart
index d6441df..5f0c9af 100644
--- a/pkg/vm/lib/metadata/inferred_type.dart
+++ b/pkg/vm/lib/metadata/inferred_type.dart
@@ -127,7 +127,7 @@
     // TODO(sjindel/tfa): Implement serialization of type arguments when can use
     // them for optimizations.
     final concreteClassReference =
-        source.readCanonicalNameReference()?.getReference();
+        source.readNullableCanonicalNameReference()?.getReference();
     final flags = source.readByte();
     final constantValue = (flags & InferredType.flagConstant) != 0
         ? source.readConstantReference()
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index fbc6871..bd9e7ad 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -6322,8 +6322,10 @@
         " HeapSize\n");
     GrowableArray<SerializationCluster*> clusters_by_size;
     for (intptr_t cid = 1; cid < num_cids_; cid++) {
-      SerializationCluster* cluster = clusters_by_cid_[cid];
-      if (cluster != NULL) {
+      if (auto const cluster = canonical_clusters_by_cid_[cid]) {
+        clusters_by_size.Add(cluster);
+      }
+      if (auto const cluster = clusters_by_cid_[cid]) {
         clusters_by_size.Add(cluster);
       }
     }
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index 30e6ef8..a39f0c6 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -56,8 +56,7 @@
   }
 }
 
-SafepointMonitorLocker::SafepointMonitorLocker(Monitor* monitor)
-    : monitor_(monitor) {
+void SafepointMonitorLocker::AcquireLock() {
   ASSERT(monitor_ != NULL);
   if (!monitor_->TryEnter()) {
     // We did not get the lock and could potentially block, so transition
@@ -72,6 +71,10 @@
   }
 }
 
+void SafepointMonitorLocker::ReleaseLock() {
+  monitor_->Exit();
+}
+
 Monitor::WaitResult SafepointMonitorLocker::Wait(int64_t millis) {
   Thread* thread = Thread::Current();
   if (thread != NULL) {
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index 7213808..b4557ae 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -259,19 +259,38 @@
  */
 class SafepointMonitorLocker : public ValueObject {
  public:
-  explicit SafepointMonitorLocker(Monitor* monitor);
-  virtual ~SafepointMonitorLocker() { monitor_->Exit(); }
+  explicit SafepointMonitorLocker(Monitor* monitor) : monitor_(monitor) {
+    AcquireLock();
+  }
+  virtual ~SafepointMonitorLocker() { ReleaseLock(); }
 
   Monitor::WaitResult Wait(int64_t millis = Monitor::kNoTimeout);
 
   void NotifyAll() { monitor_->NotifyAll(); }
 
  private:
+  friend class SafepointMonitorUnlockScope;
+
+  void AcquireLock();
+  void ReleaseLock();
+
   Monitor* const monitor_;
 
   DISALLOW_COPY_AND_ASSIGN(SafepointMonitorLocker);
 };
 
+class SafepointMonitorUnlockScope : public ValueObject {
+ public:
+  explicit SafepointMonitorUnlockScope(SafepointMonitorLocker* locker)
+      : locker_(locker) {
+    locker_->ReleaseLock();
+  }
+  ~SafepointMonitorUnlockScope() { locker_->AcquireLock(); }
+
+ private:
+  SafepointMonitorLocker* locker_;
+};
+
 class RwLock {
  public:
   RwLock() {}
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 4303b5f..636aaa3 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -1102,4 +1102,23 @@
   EXPECT(state.elapsed_us > 2 * 500 * 1000);
 }
 
+ISOLATE_UNIT_TEST_CASE(SafepointMonitorUnlockScope) {
+  // This test uses ASSERT instead of EXPECT because IsOwnedByCurrentThread is
+  // only available in debug mode. Since our vm/cc tests run in DEBUG mode that
+  // is sufficent for this test.
+  Monitor monitor;
+  {
+    SafepointMonitorLocker ml(&monitor);
+    ASSERT(monitor.IsOwnedByCurrentThread());
+    {
+      SafepointMonitorUnlockScope ml_unlocker(&ml);
+      ASSERT(!monitor.IsOwnedByCurrentThread());
+      {
+        SafepointMonitorLocker inner_ml(&monitor);
+        ASSERT(monitor.IsOwnedByCurrentThread());
+      }
+    }
+  }
+}
+
 }  // namespace dart
diff --git a/tools/VERSION b/tools/VERSION
index 91462d4..a23974c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 93
+PRERELEASE 94
 PRERELEASE_PATCH 0
\ No newline at end of file