Version 2.13.0-31.0.dev

Merge commit 'af0c951d9f2a4212594faf67317d3ddb00fc2dd8' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index afa88f5..211e5a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -245,7 +245,7 @@
 * The `--server` option to `dart pub publish` and `dart pub uploader` have been
   deprecated. Use `publish_to` in your `pubspec.yaml` or set the
   `$PUB_HOSTED_URL` environment variable.
-* `pub global activate no longer re-precompiles if current global installed was
+* `pub global activate` no longer re-precompiles if current global installed was
    same version.
 * The Flutter SDK constraint upper bound is now ignored in pubspecs and
   deprecated when publishing.
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index d8d8bfd..7900556 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -709,6 +709,7 @@
 method9a
 method9b
 mi
+migrated
 migration
 mime
 min
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index e42fe77..cd57d77 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -9371,7 +9371,7 @@
   final DartType type;
   final bool isRequired;
 
-  NamedType(this.name, this.type, {this.isRequired: false});
+  const NamedType(this.name, this.type, {this.isRequired: false});
 
   @override
   bool operator ==(Object other) => equals(other, null);
@@ -11550,3 +11550,12 @@
     return "Version(major=$major, minor=$minor)";
   }
 }
+
+/// Non-nullable `DartType` value to be used as a dummy initial value for the
+/// `List.filled` constructor.
+const DartType dartTypeDummy = const DynamicType();
+
+/// Non-nullable `NamedType` value to be used as a dummy initial value for the
+/// `List.filled` constructor.
+const NamedType namedTypeDummy =
+    const NamedType('', dartTypeDummy, isRequired: false);
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 8839438..30fc980 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -2,21 +2,19 @@
 // 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.class_hierarchy;
 
 import 'dart:collection';
 import 'dart:math';
 import 'dart:typed_data';
 
-import 'package:kernel/src/nnbd_top_merge.dart';
-
+// ignore: import_of_legacy_library_into_null_safe
 import 'ast.dart' hide MapEntry;
 import 'core_types.dart';
 import 'type_algebra.dart';
 import 'src/heap.dart';
 import 'src/legacy_erasure.dart';
+import 'src/nnbd_top_merge.dart';
 import 'src/norm.dart';
 
 typedef HandleAmbiguousSupertypes = void Function(Class, Supertype, Supertype);
@@ -32,13 +30,13 @@
 
   /// Returns the instantiation of [superclass] that is implemented by [type],
   /// or `null` if [type] does not implement [superclass] at all.
-  InterfaceType getTypeAsInstanceOf(
+  InterfaceType? getTypeAsInstanceOf(
       InterfaceType type, Class superclass, Library clientLibrary);
 
   /// Returns the type arguments of the instantiation of [superclass] that is
   /// implemented by [type], or `null` if [type] does not implement [superclass]
   /// at all.
-  List<DartType> getTypeArgumentsAsInstanceOf(
+  List<DartType>? getTypeArgumentsAsInstanceOf(
       InterfaceType type, Class superclass);
 
   /// Returns the possibly abstract interface member of [class_] with the given
@@ -50,7 +48,7 @@
   ///
   /// If multiple members with that name are inherited and not overridden, the
   /// member from the first declared supertype is returned.
-  Member getInterfaceMember(Class class_, Name name, {bool setter: false});
+  Member? getInterfaceMember(Class class_, Name name, {bool setter: false});
 
   /// Returns the least upper bound of two interface types, as defined by Dart
   /// 1.0.
@@ -74,8 +72,8 @@
 /// Interface for answering various subclassing queries.
 abstract class ClassHierarchy implements ClassHierarchyBase {
   factory ClassHierarchy(Component component, CoreTypes coreTypes,
-      {HandleAmbiguousSupertypes onAmbiguousSupertypes,
-      MixinInferrer mixinInferrer}) {
+      {HandleAmbiguousSupertypes? onAmbiguousSupertypes,
+      MixinInferrer? mixinInferrer}) {
     onAmbiguousSupertypes ??= (Class cls, Supertype a, Supertype b) {
       // See https://github.com/dart-lang/sdk/issues/32091
       throw "$cls can't implement both $a and $b";
@@ -104,12 +102,12 @@
 
   /// Returns the instantiation of [superclass] that is implemented by [class_],
   /// or `null` if [class_] does not implement [superclass] at all.
-  Supertype getClassAsInstanceOf(Class class_, Class superclass);
+  Supertype? getClassAsInstanceOf(Class class_, Class superclass);
 
   /// Returns the instantiation of [superclass] that is implemented by [type],
   /// or `null` if [type] does not implement [superclass].  [superclass] must
   /// be a generic class.
-  Supertype asInstantiationOf(Supertype type, Class superclass);
+  Supertype? asInstantiationOf(Supertype type, Class superclass);
 
   /// Returns the instance member that would respond to a dynamic dispatch of
   /// [name] to an instance of [class_], or `null` if no such member exists.
@@ -124,7 +122,7 @@
   ///
   /// If the class is abstract, abstract members are ignored and the dispatch
   /// is resolved if the class was not abstract.
-  Member getDispatchTarget(Class class_, Name name, {bool setter: false});
+  Member? getDispatchTarget(Class class_, Name name, {bool setter: false});
 
   /// Returns the list of potential targets of dynamic dispatch to an instance
   /// of [class_].
@@ -301,10 +299,12 @@
     if (firstLength != secondLength) {
       return firstLength - secondLength;
     }
-    Library firstLibrary = firstName.library;
-    Library secondLibrary = secondName.library;
+    Library? firstLibrary = firstName.library;
+    Library? secondLibrary = secondName.library;
     if (firstLibrary != secondLibrary) {
+      // ignore: unnecessary_null_comparison
       if (firstLibrary == null) return -1;
+      // ignore: unnecessary_null_comparison
       if (secondLibrary == null) return 1;
       return firstLibrary.compareTo(secondLibrary);
     }
@@ -322,7 +322,7 @@
   /// the one that occurs first in the list is returned.
   ///
   /// The list is assumed to be sorted according to [compareMembers].
-  static Member findMemberByName(List<Member> members, Name name) {
+  static Member? findMemberByName(List<Member> members, Name name) {
     int low = 0, high = members.length - 1;
     while (low <= high) {
       int mid = low + ((high - low) >> 1);
@@ -350,7 +350,7 @@
   /// Returns the single concrete target for invocation of the given interface
   /// target, or `null` if it could not be resolved or there are multiple
   /// possible targets.
-  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+  Member? getSingleTargetForInterfaceInvocation(Member interfaceTarget,
       {bool setter: false});
 }
 
@@ -360,27 +360,27 @@
 
   /// Top-down indices of all subclasses of this class, represented as
   /// interleaved begin/end interval end points.
-  Uint32List subtypeIntervalList;
+  late final Uint32List subtypeIntervalList;
 
   _ClassInfoSubtype(this.classInfo);
 }
 
 class _ClosedWorldClassHierarchySubtypes implements ClassHierarchySubtypes {
   final ClosedWorldClassHierarchy hierarchy;
-  final List<Class> _classesByTopDownIndex;
+  final List<Class?> _classesByTopDownIndex;
   final Map<Class, _ClassInfoSubtype> _infoMap = <Class, _ClassInfoSubtype>{};
   bool invalidated = false;
 
   _ClosedWorldClassHierarchySubtypes(this.hierarchy)
       : _classesByTopDownIndex =
-            new List<Class>.filled(hierarchy._infoMap.length, null) {
+            new List<Class?>.filled(hierarchy._infoMap.length, null) {
     hierarchy.allBetsOff = true;
     if (hierarchy._infoMap.isNotEmpty) {
       for (Class class_ in hierarchy._infoMap.keys) {
-        _infoMap[class_] = new _ClassInfoSubtype(hierarchy._infoMap[class_]);
+        _infoMap[class_] = new _ClassInfoSubtype(hierarchy._infoMap[class_]!);
       }
 
-      _topDownSortVisit(_infoMap[hierarchy._infoMap.keys.first]);
+      _topDownSortVisit(_infoMap[hierarchy._infoMap.keys.first]!);
     }
   }
 
@@ -395,17 +395,17 @@
     _IntervalListBuilder subtypeSetBuilder = new _IntervalListBuilder()
       ..addSingleton(index);
     for (_ClassInfo subtype in subInfo.classInfo.directExtenders) {
-      _ClassInfoSubtype subtypeInfo = _infoMap[subtype.classNode];
+      _ClassInfoSubtype subtypeInfo = _infoMap[subtype.classNode]!;
       _topDownSortVisit(subtypeInfo);
       subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
     }
     for (_ClassInfo subtype in subInfo.classInfo.directMixers) {
-      _ClassInfoSubtype subtypeInfo = _infoMap[subtype.classNode];
+      _ClassInfoSubtype subtypeInfo = _infoMap[subtype.classNode]!;
       _topDownSortVisit(subtypeInfo);
       subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
     }
     for (_ClassInfo subtype in subInfo.classInfo.directImplementers) {
-      _ClassInfoSubtype subtypeInfo = _infoMap[subtype.classNode];
+      _ClassInfoSubtype subtypeInfo = _infoMap[subtype.classNode]!;
       _topDownSortVisit(subtypeInfo);
       subtypeSetBuilder.addIntervalList(subtypeInfo.subtypeIntervalList);
     }
@@ -413,15 +413,16 @@
   }
 
   @override
-  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+  Member? getSingleTargetForInterfaceInvocation(Member interfaceTarget,
       {bool setter: false}) {
     if (invalidated) throw "This data structure has been invalidated";
     Name name = interfaceTarget.name;
-    Member target = null;
+    Member? target = null;
     ClassSet subtypes = getSubtypesOf(interfaceTarget.enclosingClass);
     for (Class c in subtypes) {
       if (!c.isAbstract) {
-        Member candidate = hierarchy.getDispatchTarget(c, name, setter: setter);
+        Member? candidate =
+            hierarchy.getDispatchTarget(c, name, setter: setter);
         if ((candidate != null) && !candidate.isAbstract) {
           if (target == null) {
             target = candidate;
@@ -438,12 +439,12 @@
   ClassSet getSubtypesOf(Class class_) {
     if (invalidated) throw "This data structure has been invalidated";
     Set<Class> result = new Set<Class>();
-    Uint32List list = _infoMap[class_].subtypeIntervalList;
+    Uint32List list = _infoMap[class_]!.subtypeIntervalList;
     for (int i = 0; i < list.length; i += 2) {
       int from = list[i];
       int to = list[i + 1];
       for (int j = from; j < to; j++) {
-        result.add(_classesByTopDownIndex[j]);
+        result.add(_classesByTopDownIndex[j]!);
       }
     }
     return new ClassSet(result);
@@ -453,16 +454,16 @@
 /// Implementation of [ClassHierarchy] for closed world.
 class ClosedWorldClassHierarchy implements ClassHierarchy {
   CoreTypes coreTypes;
-  HandleAmbiguousSupertypes _onAmbiguousSupertypes;
-  HandleAmbiguousSupertypes _onAmbiguousSupertypesNotWrapped;
-  MixinInferrer mixinInferrer;
+  late HandleAmbiguousSupertypes _onAmbiguousSupertypes;
+  late HandleAmbiguousSupertypes _onAmbiguousSupertypesNotWrapped;
+  MixinInferrer? mixinInferrer;
 
   void set onAmbiguousSupertypes(
       HandleAmbiguousSupertypes onAmbiguousSupertypes) {
     _onAmbiguousSupertypesNotWrapped = onAmbiguousSupertypes;
     _onAmbiguousSupertypes = (Class class_, Supertype a, Supertype b) {
       onAmbiguousSupertypes(class_, a, b);
-      List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
+      List<Supertype>? recorded = _recordedAmbiguousSupertypes[class_];
       if (recorded == null) {
         recorded = <Supertype>[];
         _recordedAmbiguousSupertypes[class_] = recorded;
@@ -484,9 +485,12 @@
     return result;
   }
 
-  _ClassInfo infoFor(Class c) {
-    _ClassInfo info = _infoMap[c];
-    info?.used = true;
+  _ClassInfo infoFor(Class cls) {
+    _ClassInfo? info = _infoMap[cls];
+    if (info == null) {
+      throw "${cls.fileUri}: No class info for ${cls.name}";
+    }
+    info.used = true;
     return info;
   }
 
@@ -525,7 +529,7 @@
     return _infoMap.length;
   }
 
-  _ClosedWorldClassHierarchySubtypes _cachedClassHierarchySubtypes;
+  _ClosedWorldClassHierarchySubtypes? _cachedClassHierarchySubtypes;
 
   ClosedWorldClassHierarchy._internal(this.coreTypes,
       HandleAmbiguousSupertypes onAmbiguousSupertypes, this.mixinInferrer) {
@@ -535,7 +539,7 @@
   ClassHierarchySubtypes computeSubtypesInformation() {
     _cachedClassHierarchySubtypes ??=
         new _ClosedWorldClassHierarchySubtypes(this);
-    return _cachedClassHierarchySubtypes;
+    return _cachedClassHierarchySubtypes!;
   }
 
   @override
@@ -570,11 +574,11 @@
   }
 
   List<_ClassInfo> _getRankedSuperclassInfos(_ClassInfo info) {
-    if (info.leastUpperBoundInfos != null) return info.leastUpperBoundInfos;
+    if (info.leastUpperBoundInfos != null) return info.leastUpperBoundInfos!;
     _LubHeap heap = new _LubHeap()..add(info);
     List<_ClassInfo> chain = <_ClassInfo>[];
     info.leastUpperBoundInfos = chain;
-    _ClassInfo lastInfo = null;
+    _ClassInfo? lastInfo = null;
     while (heap.isNotEmpty) {
       _ClassInfo nextInfo = heap.remove();
       if (identical(nextInfo, lastInfo)) continue;
@@ -641,7 +645,7 @@
     // single candidate.
     int i1 = 0;
     int i2 = 0;
-    InterfaceType candidate = null;
+    InterfaceType? candidate = null;
     int currentDepth = -1;
     int numCandidatesAtThisDepth = 0;
     while (true) {
@@ -663,7 +667,7 @@
       }
       if (next.depth != currentDepth) {
         if (numCandidatesAtThisDepth == 1) {
-          return candidate;
+          return candidate!;
         }
         currentDepth = next.depth;
         numCandidatesAtThisDepth = 0;
@@ -692,14 +696,16 @@
         InterfaceType superType1 = identical(info1, next)
             ? type1
             : Substitution.fromInterfaceType(type1).substituteType(
-                info1.genericSuperType[next.classNode].asInterfaceType);
+                    info1.genericSuperType![next.classNode]!.asInterfaceType)
+                as InterfaceType;
         InterfaceType superType2 = identical(info2, next)
             ? type2
             : Substitution.fromInterfaceType(type2).substituteType(
-                info2.genericSuperType[next.classNode].asInterfaceType);
+                    info2.genericSuperType![next.classNode]!.asInterfaceType)
+                as InterfaceType;
         if (!clientLibrary.isNonNullableByDefault) {
-          superType1 = legacyErasure(superType1);
-          superType2 = legacyErasure(superType2);
+          superType1 = legacyErasure(superType1) as InterfaceType;
+          superType2 = legacyErasure(superType2) as InterfaceType;
         }
         if (superType1 == superType2) {
           candidate = superType1.withDeclaredNullability(
@@ -711,27 +717,21 @@
   }
 
   @override
-  Supertype getClassAsInstanceOf(Class class_, Class superclass) {
+  Supertype? getClassAsInstanceOf(Class class_, Class superclass) {
     if (identical(class_, superclass)) return class_.asThisSupertype;
     _ClassInfo info = infoFor(class_);
-    if (info == null) {
-      throw "${class_.fileUri}: No class info for ${class_.name}";
-    }
     _ClassInfo superInfo = infoFor(superclass);
-    if (superInfo == null) {
-      throw "${superclass.fileUri}: No class info for ${superclass.name}";
-    }
     if (!info.isSubtypeOf(superInfo)) return null;
     if (superclass.typeParameters.isEmpty) return superclass.asRawSupertype;
-    assert(info.genericSuperType.containsKey(superclass),
+    assert(info.genericSuperType!.containsKey(superclass),
         "No canonical instance of $superclass found for $class_.");
-    return info.genericSuperType[superclass];
+    return info.genericSuperType![superclass];
   }
 
   @override
-  InterfaceType getTypeAsInstanceOf(
+  InterfaceType? getTypeAsInstanceOf(
       InterfaceType type, Class superclass, Library clientLibrary) {
-    List<DartType> typeArguments =
+    List<DartType>? typeArguments =
         getTypeArgumentsAsInstanceOf(type, superclass);
     if (typeArguments == null) return null;
     // The return value should be a legacy type if it's computed for an
@@ -744,7 +744,7 @@
   }
 
   @override
-  List<DartType> getTypeArgumentsAsInstanceOf(
+  List<DartType>? getTypeArgumentsAsInstanceOf(
       InterfaceType type, Class superclass) {
     if (type.classNode == superclass) {
       // TODO(johnniwinther): This is necessary because [getClassAsInstanceOf]
@@ -759,7 +759,7 @@
       // situations.
       return type.typeArguments;
     }
-    Supertype castedType = getClassAsInstanceOf(type.classNode, superclass);
+    Supertype? castedType = getClassAsInstanceOf(type.classNode, superclass);
     if (castedType == null) return null;
     if (superclass.typeParameters.isEmpty) return const <DartType>[];
     return Substitution.fromInterfaceType(type)
@@ -768,10 +768,10 @@
   }
 
   @override
-  Member getDispatchTarget(Class class_, Name name, {bool setter: false}) {
+  Member? getDispatchTarget(Class class_, Name name, {bool setter: false}) {
     List<Member> list =
         _buildImplementedMembers(class_, infoFor(class_), setters: setter);
-    Member member = ClassHierarchy.findMemberByName(list, name);
+    Member? member = ClassHierarchy.findMemberByName(list, name);
     assert(
         member == null || !member.isAbstract,
         "Abstract member $member found as dispatch target "
@@ -785,7 +785,7 @@
   }
 
   @override
-  Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
+  Member? getInterfaceMember(Class class_, Name name, {bool setter: false}) {
     List<Member> list = getInterfaceMembers(class_, setters: setter);
     return ClassHierarchy.findMemberByName(list, name);
   }
@@ -845,7 +845,7 @@
 
   @override
   List<Supertype> genericSupertypesOf(Class class_) {
-    Map<Class, Supertype> supertypes = infoFor(class_).genericSuperType;
+    Map<Class, Supertype>? supertypes = infoFor(class_).genericSuperType;
     if (supertypes == null) return const <Supertype>[];
     return supertypes.values.toList();
   }
@@ -853,47 +853,41 @@
   @override
   ClassHierarchy applyTreeChanges(Iterable<Library> removedLibraries,
       Iterable<Library> ensureKnownLibraries, Iterable<Class> updatedClasses,
-      {Component reissueAmbiguousSupertypesFor}) {
+      {Component? reissueAmbiguousSupertypesFor}) {
     Set<_ClassInfo> changedClasses = <_ClassInfo>{};
 
     void removeClass(Class cls) {
-      _ClassInfo info = _infoMap[cls];
+      _ClassInfo? info = _infoMap[cls];
       if (info == null) return;
       if (cls.supertype != null) {
-        _infoMap[cls.supertype.classNode]?.directExtenders?.remove(info);
+        _infoMap[cls.supertype.classNode]?.directExtenders.remove(info);
       }
       if (cls.mixedInType != null) {
-        _infoMap[cls.mixedInType.classNode]?.directMixers?.remove(info);
+        _infoMap[cls.mixedInType.classNode]?.directMixers.remove(info);
       }
       for (Supertype supertype in cls.implementedTypes) {
-        _infoMap[supertype.classNode]?.directImplementers?.remove(info);
+        _infoMap[supertype.classNode]?.directImplementers.remove(info);
         // Remove from directMixers too as the mixin transformation will
         // "move" the type here.
         if (cls.isAnonymousMixin || cls.isEliminatedMixin) {
-          _infoMap[supertype.classNode]?.directMixers?.remove(info);
+          _infoMap[supertype.classNode]?.directMixers.remove(info);
         }
       }
       _infoMap.remove(cls);
       _recordedAmbiguousSupertypes.remove(cls);
     }
 
-    void invalidateClass(_ClassInfo info) {
+    void invalidateClass(_ClassInfo? info) {
       if (info == null) return;
       if (!changedClasses.add(info)) return;
-      if (info.directExtenders != null) {
-        for (_ClassInfo i in info.directExtenders.toList()) {
-          invalidateClass(i);
-        }
+      for (_ClassInfo i in info.directExtenders.toList()) {
+        invalidateClass(i);
       }
-      if (info.directMixers != null) {
-        for (_ClassInfo i in info.directMixers.toList()) {
-          invalidateClass(i);
-        }
+      for (_ClassInfo i in info.directMixers.toList()) {
+        invalidateClass(i);
       }
-      if (info.directImplementers != null) {
-        for (_ClassInfo i in info.directImplementers.toList()) {
-          invalidateClass(i);
-        }
+      for (_ClassInfo i in info.directImplementers.toList()) {
+        invalidateClass(i);
       }
       removeClass(info.classNode);
     }
@@ -914,7 +908,7 @@
     // If we have a cached computation of subtypes, invalidate it and stop
     // caching it.
     if (_cachedClassHierarchySubtypes != null) {
-      _cachedClassHierarchySubtypes.invalidated = true;
+      _cachedClassHierarchySubtypes!.invalidated = true;
     }
 
     if (_recordedAmbiguousSupertypes.isNotEmpty &&
@@ -923,7 +917,7 @@
           new Set<Library>.from(reissueAmbiguousSupertypesFor.libraries);
       for (Class class_ in _recordedAmbiguousSupertypes.keys) {
         if (!libs.contains(class_.enclosingLibrary)) continue;
-        List<Supertype> recorded = _recordedAmbiguousSupertypes[class_];
+        List<Supertype> recorded = _recordedAmbiguousSupertypes[class_]!;
         for (int i = 0; i < recorded.length; i += 2) {
           _onAmbiguousSupertypesNotWrapped(
               class_, recorded[i], recorded[i + 1]);
@@ -1001,14 +995,14 @@
     Map<String, List<Class>> map = {};
     for (Class c in _infoMap.keys) {
       String className = "${c.enclosingLibrary.importUri}::${c.name}";
-      List<Class> list = map[className];
+      List<Class>? list = map[className];
       if (list == null) {
         map[className] = list = [];
       }
       list.add(c);
     }
 
-    StringBuffer sb;
+    StringBuffer? sb;
     for (MapEntry<String, List<Class>> entry in map.entries) {
       if (entry.value.length != 1) {
         sb ??= new StringBuffer();
@@ -1047,7 +1041,7 @@
   }
 
   @override
-  Supertype asInstantiationOf(Supertype type, Class superclass) {
+  Supertype? asInstantiationOf(Supertype type, Class superclass) {
     // This is similar to getTypeAsInstanceOf, except that it assumes that
     // superclass is a generic class.  It thus does not rely on being able
     // to answer isSubtypeOf queries and so can be used before we have built
@@ -1056,7 +1050,7 @@
     if (type.classNode == superclass) {
       return superclass.asThisSupertype;
     }
-    Map<Class, Supertype> map = infoFor(type.classNode)?.genericSuperType;
+    Map<Class, Supertype>? map = infoFor(type.classNode).genericSuperType;
     return map == null ? null : map[superclass];
   }
 
@@ -1083,15 +1077,19 @@
       Iterable<Class> classes, int expectedStartingTopologicalIndex) {
     int i = expectedStartingTopologicalIndex;
     for (Class class_ in classes) {
-      _ClassInfo info = _infoMap[class_];
+      _ClassInfo? info = _infoMap[class_];
+      if (info == null) {
+        throw "No info for ${class_.name} from ${class_.fileUri}.";
+      }
+
       if (class_.supertype != null) {
-        _infoMap[class_.supertype.classNode].directExtenders.add(info);
+        _infoMap[class_.supertype!.classNode]!.directExtenders.add(info);
       }
       if (class_.mixedInType != null) {
-        _infoMap[class_.mixedInType.classNode].directMixers.add(info);
+        _infoMap[class_.mixedInType!.classNode]!.directMixers.add(info);
       }
       for (Supertype supertype in class_.implementedTypes) {
-        _infoMap[supertype.classNode].directImplementers.add(info);
+        _infoMap[supertype.classNode]!.directImplementers.add(info);
       }
       _collectSupersForClass(class_);
 
@@ -1106,9 +1104,6 @@
         _recordSuperTypes(info, supertype);
       }
 
-      if (info == null) {
-        throw "No info for ${class_.name} from ${class_.fileUri}.";
-      }
       if (info.topologicalIndex != i) {
         throw "Unexpected topologicalIndex (${info.topologicalIndex} != $i) "
             "for ${class_.name} from ${class_.fileUri}.";
@@ -1124,8 +1119,8 @@
   /// inheritance path to the root class).
   int _topSortIndex = 0;
   int _topologicalSortVisit(Class classNode, Set<Class> beingVisited,
-      {List<Class> orderedList}) {
-    _ClassInfo info = _infoMap[classNode];
+      {List<Class>? orderedList}) {
+    _ClassInfo? info = _infoMap[classNode];
     if (info != null) {
       return info.depth;
     }
@@ -1140,13 +1135,13 @@
     if (classNode.supertype != null) {
       superDepth = max(
           superDepth,
-          _topologicalSortVisit(classNode.supertype.classNode, beingVisited,
+          _topologicalSortVisit(classNode.supertype!.classNode, beingVisited,
               orderedList: orderedList));
     }
     if (classNode.mixedInType != null) {
       superDepth = max(
           superDepth,
-          _topologicalSortVisit(classNode.mixedInType.classNode, beingVisited,
+          _topologicalSortVisit(classNode.mixedInType!.classNode, beingVisited,
               orderedList: orderedList));
     }
     for (Supertype supertype in classNode.implementedTypes) {
@@ -1165,11 +1160,8 @@
   }
 
   List<Member> _buildImplementedMembers(Class classNode, _ClassInfo info,
-      {bool setters}) {
-    if (info == null) {
-      throw "${classNode.fileUri}: No class info for ${classNode.name}";
-    }
-    List<Member> members = setters
+      {required bool setters}) {
+    List<Member>? members = setters
         ? info.lazyImplementedSetters
         : info.lazyImplementedGettersAndCalls;
     if (members != null) return members;
@@ -1179,7 +1171,7 @@
       inherited = const <Member>[];
     } else {
       Class superClassNode = classNode.supertype.classNode;
-      _ClassInfo superInfo = _infoMap[superClassNode];
+      _ClassInfo superInfo = _infoMap[superClassNode]!;
       inherited =
           _buildImplementedMembers(superClassNode, superInfo, setters: setters);
     }
@@ -1195,11 +1187,8 @@
   }
 
   List<Member> _buildDeclaredMembers(Class classNode, _ClassInfo info,
-      {bool setters}) {
-    if (info == null) {
-      throw "${classNode.fileUri}: No class info for ${classNode.name}";
-    }
-    List<Member> members =
+      {required bool setters}) {
+    List<Member>? members =
         setters ? info.lazyDeclaredSetters : info.lazyDeclaredGettersAndCalls;
     if (members != null) return members;
 
@@ -1209,8 +1198,8 @@
     // declared members can replace mixed in members.
     Map<Name, Member> memberMap = {};
     if (classNode.mixedInType != null) {
-      Class mixedInClassNode = classNode.mixedInType.classNode;
-      _ClassInfo mixedInInfo = _infoMap[mixedInClassNode];
+      Class mixedInClassNode = classNode.mixedInType!.classNode;
+      _ClassInfo mixedInInfo = _infoMap[mixedInClassNode]!;
 
       for (Member mixinMember in _buildDeclaredMembers(
           mixedInClassNode, mixedInInfo,
@@ -1256,21 +1245,18 @@
   }
 
   List<Member> _buildInterfaceMembers(Class classNode, _ClassInfo info,
-      {bool setters}) {
-    if (info == null) {
-      throw "${classNode.fileUri}: No class info for ${classNode.name}";
-    }
-    List<Member> members =
+      {required bool setters}) {
+    List<Member>? members =
         setters ? info.lazyInterfaceSetters : info.lazyInterfaceGettersAndCalls;
     if (members != null) return members;
     List<Member> allInheritedMembers = <Member>[];
     List<Member> declared =
         _buildDeclaredMembers(classNode, info, setters: setters);
 
-    void inheritFrom(Supertype type) {
+    void inheritFrom(Supertype? type) {
       if (type == null) return;
       List<Member> inherited = _buildInterfaceMembers(
-          type.classNode, _infoMap[type.classNode],
+          type.classNode, _infoMap[type.classNode]!,
           setters: setters);
       inherited = _getUnshadowedInheritedMembers(declared, inherited);
       allInheritedMembers =
@@ -1376,7 +1362,7 @@
   }
 
   void _recordSuperTypes(_ClassInfo subInfo, Supertype supertype) {
-    _ClassInfo superInfo = _infoMap[supertype.classNode];
+    _ClassInfo superInfo = _infoMap[supertype.classNode]!;
     if (supertype.typeArguments.isEmpty) {
       if (superInfo.genericSuperTypes == null) return;
       // Copy over the super type entries.
@@ -1408,7 +1394,7 @@
   /// Note that the super class and super types of the class must already have
   /// had their supers collected.
   void _collectSupersForClass(Class class_) {
-    _ClassInfo info = _infoMap[class_];
+    _ClassInfo info = _infoMap[class_]!;
 
     _IntervalListBuilder superclassSetBuilder = new _IntervalListBuilder()
       ..addSingleton(info.topologicalIndex);
@@ -1416,20 +1402,20 @@
       ..addSingleton(info.topologicalIndex);
 
     if (class_.supertype != null) {
-      _ClassInfo supertypeInfo = _infoMap[class_.supertype.classNode];
+      _ClassInfo supertypeInfo = _infoMap[class_.supertype!.classNode]!;
       superclassSetBuilder
           .addIntervalList(supertypeInfo.superclassIntervalList);
       supertypeSetBuilder.addIntervalList(supertypeInfo.supertypeIntervalList);
     }
 
     if (class_.mixedInType != null) {
-      _ClassInfo mixedInTypeInfo = _infoMap[class_.mixedInType.classNode];
+      _ClassInfo mixedInTypeInfo = _infoMap[class_.mixedInType!.classNode]!;
       supertypeSetBuilder
           .addIntervalList(mixedInTypeInfo.supertypeIntervalList);
     }
 
     for (Supertype supertype in class_.implementedTypes) {
-      _ClassInfo supertypeInfo = _infoMap[supertype.classNode];
+      _ClassInfo supertypeInfo = _infoMap[supertype.classNode]!;
       supertypeSetBuilder.addIntervalList(supertypeInfo.supertypeIntervalList);
     }
 
@@ -1445,7 +1431,7 @@
   List<int> getExpenseHistogram() {
     List<int> result = <int>[];
     for (Class class_ in _infoMap.keys) {
-      _ClassInfo info = _infoMap[class_];
+      _ClassInfo info = _infoMap[class_]!;
       int intervals = info.supertypeIntervalList.length ~/ 2;
       if (intervals >= result.length) {
         int oldLength = result.length;
@@ -1466,7 +1452,7 @@
     int intervals = 0;
     int sizes = 0;
     for (Class class_ in _infoMap.keys) {
-      _ClassInfo info = _infoMap[class_];
+      _ClassInfo info = _infoMap[class_]!;
       intervals += (info.superclassIntervalList.length +
               info.supertypeIntervalList.length) ~/
           2;
@@ -1481,7 +1467,7 @@
   int getSuperTypeHashTableSize() {
     int sum = 0;
     for (Class class_ in _infoMap.keys) {
-      sum += _infoMap[class_].genericSuperTypes?.length ?? 0;
+      sum += _infoMap[class_]!.genericSuperTypes?.length ?? 0;
     }
     return sum;
   }
@@ -1574,12 +1560,12 @@
 
 class ForTestingClassInfo {
   final Class classNode;
-  final List<Member> lazyDeclaredGettersAndCalls;
-  final List<Member> lazyDeclaredSetters;
-  final List<Member> lazyImplementedGettersAndCalls;
-  final List<Member> lazyImplementedSetters;
-  final List<Member> lazyInterfaceGettersAndCalls;
-  final List<Member> lazyInterfaceSetters;
+  final List<Member>? lazyDeclaredGettersAndCalls;
+  final List<Member>? lazyDeclaredSetters;
+  final List<Member>? lazyImplementedGettersAndCalls;
+  final List<Member>? lazyImplementedSetters;
+  final List<Member>? lazyInterfaceGettersAndCalls;
+  final List<Member>? lazyInterfaceSetters;
 
   ForTestingClassInfo._(_ClassInfo c)
       : classNode = c.classNode,
@@ -1609,17 +1595,17 @@
   final Set<_ClassInfo> directMixers = new LinkedHashSet<_ClassInfo>();
   final Set<_ClassInfo> directImplementers = new LinkedHashSet<_ClassInfo>();
 
-  Uint32List superclassIntervalList;
-  Uint32List supertypeIntervalList;
+  late final Uint32List superclassIntervalList;
+  late final Uint32List supertypeIntervalList;
 
-  List<_ClassInfo> leastUpperBoundInfos;
+  List<_ClassInfo>? leastUpperBoundInfos;
 
   /// Maps generic supertype classes to the instantiations implemented by this
   /// class.
   ///
   /// E.g. `List` maps to `List<String>` for a class that directly or indirectly
   /// implements `List<String>`.
-  Map<Class, List<Supertype>> genericSuperTypes;
+  Map<Class, List<Supertype>>? genericSuperTypes;
 
   /// Maps generic supertype classes to the canonical instantiation implemented
   /// by this class.
@@ -1627,26 +1613,26 @@
   /// E.g. `List` maps to `List<String>` for a class that directly or indirectly
   /// implements `List<String>`.
 
-  Map<Class, Supertype> genericSuperType;
+  Map<Class, Supertype>? genericSuperType;
 
   /// Instance fields, getters, methods, and operators declared in this class
   /// or its mixed-in class, sorted according to [_compareMembers].
-  List<Member> lazyDeclaredGettersAndCalls;
+  List<Member>? lazyDeclaredGettersAndCalls;
 
   /// Non-final instance fields and setters declared in this class or its
   /// mixed-in class, sorted according to [_compareMembers].
-  List<Member> lazyDeclaredSetters;
+  List<Member>? lazyDeclaredSetters;
 
   /// Instance fields, getters, methods, and operators implemented by this class
   /// (declared or inherited).
-  List<Member> lazyImplementedGettersAndCalls;
+  List<Member>? lazyImplementedGettersAndCalls;
 
   /// Non-final instance fields and setters implemented by this class
   /// (declared or inherited).
-  List<Member> lazyImplementedSetters;
+  List<Member>? lazyImplementedSetters;
 
-  List<Member> lazyInterfaceGettersAndCalls;
-  List<Member> lazyInterfaceSetters;
+  List<Member>? lazyInterfaceGettersAndCalls;
+  List<Member>? lazyInterfaceSetters;
 
   _ClassInfo(this.classNode);
 
@@ -1661,29 +1647,30 @@
 
   void recordGenericSuperType(CoreTypes coreTypes, Class cls, Supertype type,
       HandleAmbiguousSupertypes onAmbiguousSupertypes) {
-    Supertype canonical = genericSuperType[cls];
+    Supertype? canonical = genericSuperType![cls];
     if (canonical == null) {
       if (!classNode.enclosingLibrary.isNonNullableByDefault) {
         canonical = legacyErasureSupertype(type);
       } else {
         canonical = type;
       }
+      // ignore: unnecessary_null_comparison
       assert(canonical != null,
           "No canonical instantiation computed for $cls in $classNode.");
-      genericSuperType[cls] = canonical;
-      genericSuperTypes[cls] = <Supertype>[type];
+      genericSuperType![cls] = canonical;
+      genericSuperTypes![cls] = <Supertype>[type];
     } else {
-      genericSuperTypes[cls].add(type);
+      genericSuperTypes![cls]!.add(type);
 
       if (classNode.enclosingLibrary.isNonNullableByDefault) {
-        Supertype result = nnbdTopMergeSupertype(
+        Supertype? result = nnbdTopMergeSupertype(
             coreTypes,
             normSupertype(coreTypes, type),
             normSupertype(coreTypes, canonical));
         if (result == null) {
           onAmbiguousSupertypes(classNode, canonical, type);
         } else {
-          genericSuperType[cls] = result;
+          genericSuperType![cls] = result;
         }
       } else {
         type = legacyErasureSupertype(type);
@@ -1692,9 +1679,9 @@
         }
       }
     }
-    assert(genericSuperType.containsKey(cls),
+    assert(genericSuperType!.containsKey(cls),
         "No canonical instantiation computed for $cls in $classNode.");
-    assert(genericSuperTypes.containsKey(cls),
+    assert(genericSuperTypes!.containsKey(cls),
         "No instantiations computed for $cls in $classNode.");
   }
 }
@@ -1704,7 +1691,7 @@
   final Set<Class> _classes;
   ClassSet(this._classes);
 
-  bool contains(Object class_) {
+  bool contains(Object? class_) {
     return _classes.contains(class_);
   }
 
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 9fa6f5a..2fa52ac 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -7,7 +7,6 @@
 // ignore: import_of_legacy_library_into_null_safe
 import 'ast.dart';
 import 'library_index.dart';
-// ignore: import_of_legacy_library_into_null_safe
 import 'type_algebra.dart';
 
 /// Provides access to the classes and libraries in the core libraries.
diff --git a/pkg/kernel/lib/src/hierarchy_based_type_environment.dart b/pkg/kernel/lib/src/hierarchy_based_type_environment.dart
index e259b73..4a02f4e 100644
--- a/pkg/kernel/lib/src/hierarchy_based_type_environment.dart
+++ b/pkg/kernel/lib/src/hierarchy_based_type_environment.dart
@@ -2,10 +2,9 @@
 // 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.hierarchy_based_type_environment;
 
+// ignore: import_of_legacy_library_into_null_safe
 import '../ast.dart' show Class, DartType, InterfaceType, Library, Member, Name;
 
 import '../class_hierarchy.dart' show ClassHierarchyBase;
@@ -21,20 +20,20 @@
       : super.fromSubclass(coreTypes, hierarchy);
 
   @override
-  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
+  InterfaceType? getTypeAsInstanceOf(InterfaceType type, Class superclass,
       Library clientLibrary, CoreTypes coreTypes) {
     return hierarchy.getTypeAsInstanceOf(type, superclass, clientLibrary);
   }
 
   @override
-  List<DartType> getTypeArgumentsAsInstanceOf(
+  List<DartType>? getTypeArgumentsAsInstanceOf(
       InterfaceType type, Class superclass) {
     if (type.classNode == superclass) return type.typeArguments;
     return hierarchy.getTypeArgumentsAsInstanceOf(type, superclass);
   }
 
   @override
-  Member getInterfaceMember(Class cls, Name name, {bool setter: false}) {
+  Member? getInterfaceMember(Class cls, Name name, {bool setter: false}) {
     return hierarchy.getInterfaceMember(cls, name, setter: setter);
   }
 }
diff --git a/pkg/kernel/lib/src/legacy_erasure.dart b/pkg/kernel/lib/src/legacy_erasure.dart
index 7a36398..fee2dc4 100644
--- a/pkg/kernel/lib/src/legacy_erasure.dart
+++ b/pkg/kernel/lib/src/legacy_erasure.dart
@@ -2,8 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-// @dart = 2.9
-
+// ignore: import_of_legacy_library_into_null_safe
 import '../ast.dart' hide MapEntry;
 
 import 'replacement_visitor.dart';
@@ -20,7 +19,7 @@
 /// named parameters are not required.
 ///
 /// Returns `null` if the type wasn't changed.
-DartType rawLegacyErasure(DartType type) {
+DartType? rawLegacyErasure(DartType type) {
   return type.accept1(const _LegacyErasure(), Variance.covariant);
 }
 
@@ -31,10 +30,10 @@
   if (supertype.typeArguments.isEmpty) {
     return supertype;
   }
-  List<DartType> newTypeArguments;
+  List<DartType>? newTypeArguments;
   for (int i = 0; i < supertype.typeArguments.length; i++) {
     DartType typeArgument = supertype.typeArguments[i];
-    DartType newTypeArgument =
+    DartType? newTypeArgument =
         typeArgument.accept1(const _LegacyErasure(), Variance.covariant);
     if (newTypeArgument != null) {
       newTypeArguments ??= supertype.typeArguments.toList(growable: false);
@@ -54,7 +53,7 @@
 class _LegacyErasure extends ReplacementVisitor {
   const _LegacyErasure();
 
-  Nullability visitNullability(DartType node) {
+  Nullability? visitNullability(DartType node) {
     if (node.declaredNullability != Nullability.legacy) {
       return Nullability.legacy;
     }
@@ -62,7 +61,7 @@
   }
 
   @override
-  NamedType createNamedType(NamedType node, DartType newType) {
+  NamedType? createNamedType(NamedType node, DartType? newType) {
     if (node.isRequired || newType != null) {
       return new NamedType(node.name, newType ?? node.type, isRequired: false);
     }
@@ -101,7 +100,7 @@
 ///    }
 ///
 bool needsLegacyErasure(Class enclosingClass, Class declaringClass) {
-  Class cls = enclosingClass;
+  Class? cls = enclosingClass;
   while (cls != null) {
     if (!cls.enclosingLibrary.isNonNullableByDefault) {
       return true;
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index 75505b6..de66d20 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -2,26 +2,25 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-// @dart = 2.9
-
+// ignore: import_of_legacy_library_into_null_safe
 import '../ast.dart' hide MapEntry;
 import '../type_algebra.dart';
 
 /// Helper visitor that merges two types, and return the merged type or `null`
 /// if the types could not be merged.
-class MergeVisitor implements DartTypeVisitor1<DartType, DartType> {
-  Nullability mergeNullability(Nullability a, Nullability b) {
+class MergeVisitor implements DartTypeVisitor1<DartType?, DartType> {
+  Nullability? mergeNullability(Nullability a, Nullability b) {
     return a == b ? a : null;
   }
 
   @override
-  DartType visitFunctionType(FunctionType a, DartType b) {
+  DartType? visitFunctionType(FunctionType a, DartType b) {
     if (b is FunctionType &&
         a.typeParameters.length == b.typeParameters.length &&
         a.requiredParameterCount == b.requiredParameterCount &&
         a.positionalParameters.length == b.positionalParameters.length &&
         a.namedParameters.length == b.namedParameters.length) {
-      Nullability nullability = mergeNullability(a.nullability, b.nullability);
+      Nullability? nullability = mergeNullability(a.nullability, b.nullability);
       if (nullability != null) {
         return mergeFunctionTypes(a, b, nullability);
       }
@@ -29,7 +28,7 @@
     return null;
   }
 
-  FunctionType mergeFunctionTypes(
+  FunctionType? mergeFunctionTypes(
       FunctionType a, FunctionType b, Nullability nullability) {
     assert(a.typeParameters.length == b.typeParameters.length);
     assert(a.requiredParameterCount == b.requiredParameterCount);
@@ -37,51 +36,49 @@
     assert(a.namedParameters.length == b.namedParameters.length);
 
     List<TypeParameter> newTypeParameters =
-        new List<TypeParameter>.filled(a.typeParameters.length, null);
-    for (int i = 0; i < a.typeParameters.length; i++) {
+        new List<TypeParameter>.generate(a.typeParameters.length, (int i) {
       TypeParameter aTypeParameter = a.typeParameters[i];
       TypeParameter bTypeParameter = b.typeParameters[i];
-      newTypeParameters[i] =
-          new TypeParameter(aTypeParameter.name ?? bTypeParameter.name);
-    }
+      return new TypeParameter(aTypeParameter.name ?? bTypeParameter.name);
+    }, growable: false);
 
-    Substitution aSubstitution;
-    Substitution bSubstitution;
+    Substitution? aSubstitution;
+    Substitution? bSubstitution;
 
-    DartType mergeTypes(DartType a, DartType b) {
+    DartType? mergeTypes(DartType a, DartType b) {
       if (aSubstitution != null) {
         a = aSubstitution.substituteType(a);
-        b = bSubstitution.substituteType(b);
+        b = bSubstitution!.substituteType(b);
       }
       return a.accept1(this, b);
     }
 
     if (newTypeParameters.isNotEmpty) {
       List<TypeParameterType> aTypeParameterTypes =
-          new List<TypeParameterType>.filled(newTypeParameters.length, null);
-      for (int i = 0; i < newTypeParameters.length; i++) {
-        aTypeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
+          new List<TypeParameterType>.generate(newTypeParameters.length,
+              (int i) {
+        return new TypeParameterType.forAlphaRenaming(
             a.typeParameters[i], newTypeParameters[i]);
-      }
+      }, growable: false);
       aSubstitution =
           Substitution.fromPairs(a.typeParameters, aTypeParameterTypes);
       List<TypeParameterType> bTypeParameterTypes =
-          new List<TypeParameterType>.filled(newTypeParameters.length, null);
-      for (int i = 0; i < newTypeParameters.length; i++) {
-        bTypeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
+          new List<TypeParameterType>.generate(newTypeParameters.length,
+              (int i) {
+        return new TypeParameterType.forAlphaRenaming(
             b.typeParameters[i], newTypeParameters[i]);
-      }
+      }, growable: false);
       bSubstitution =
           Substitution.fromPairs(b.typeParameters, bTypeParameterTypes);
 
       for (int i = 0; i < newTypeParameters.length; i++) {
-        DartType newBound =
+        DartType? newBound =
             mergeTypes(a.typeParameters[i].bound, b.typeParameters[i].bound);
         if (newBound == null) {
           return null;
         }
         newTypeParameters[i].bound = newBound;
-        DartType newDefaultType = mergeTypes(
+        DartType? newDefaultType = mergeTypes(
             a.typeParameters[i].defaultType, b.typeParameters[i].defaultType);
         if (newDefaultType == null) {
           return null;
@@ -90,12 +87,12 @@
       }
     }
 
-    DartType newReturnType = mergeTypes(a.returnType, b.returnType);
+    DartType? newReturnType = mergeTypes(a.returnType, b.returnType);
     if (newReturnType == null) return null;
     List<DartType> newPositionalParameters =
-        new List<DartType>.filled(a.positionalParameters.length, null);
+        new List<DartType>.filled(a.positionalParameters.length, dartTypeDummy);
     for (int i = 0; i < a.positionalParameters.length; i++) {
-      DartType newType =
+      DartType? newType =
           mergeTypes(a.positionalParameters[i], b.positionalParameters[i]);
       if (newType == null) {
         return null;
@@ -103,23 +100,23 @@
       newPositionalParameters[i] = newType;
     }
     List<NamedType> newNamedParameters =
-        new List<NamedType>.filled(a.namedParameters.length, null);
+        new List<NamedType>.filled(a.namedParameters.length, namedTypeDummy);
     for (int i = 0; i < a.namedParameters.length; i++) {
-      DartType newType =
+      DartType? newType =
           mergeTypes(a.namedParameters[i].type, b.namedParameters[i].type);
       if (newType == null) {
         return null;
       }
-      NamedType newNamedType =
+      NamedType? newNamedType =
           mergeNamedTypes(a.namedParameters[i], b.namedParameters[i], newType);
       if (newNamedType == null) {
         return null;
       }
       newNamedParameters[i] = newNamedType;
     }
-    DartType newTypedefType;
+    TypedefType? newTypedefType;
     if (a.typedefType != null) {
-      newTypedefType = mergeTypes(a.typedefType, b.typedefType);
+      newTypedefType = mergeTypes(a.typedefType, b.typedefType) as TypedefType?;
       if (newTypedefType == null) return null;
     }
 
@@ -130,7 +127,7 @@
         typedefType: newTypedefType);
   }
 
-  NamedType mergeNamedTypes(NamedType a, NamedType b, DartType newType) {
+  NamedType? mergeNamedTypes(NamedType a, NamedType b, DartType newType) {
     if (a.name != b.name || a.isRequired != b.isRequired) {
       return null;
     } else {
@@ -139,11 +136,11 @@
   }
 
   @override
-  DartType visitInterfaceType(InterfaceType a, DartType b) {
+  DartType? visitInterfaceType(InterfaceType a, DartType b) {
     if (b is InterfaceType &&
         a.classNode == b.classNode &&
         a.typeArguments.length == b.typeArguments.length) {
-      Nullability nullability = mergeNullability(a.nullability, b.nullability);
+      Nullability? nullability = mergeNullability(a.nullability, b.nullability);
       if (nullability != null) {
         return mergeInterfaceTypes(a, b, nullability);
       }
@@ -151,7 +148,7 @@
     return null;
   }
 
-  DartType mergeInterfaceTypes(
+  DartType? mergeInterfaceTypes(
       InterfaceType a, InterfaceType b, Nullability nullability) {
     assert(a.classNode == b.classNode);
     assert(a.typeArguments.length == b.typeArguments.length);
@@ -159,9 +156,9 @@
       return new InterfaceType(a.classNode, nullability);
     }
     List<DartType> newTypeArguments =
-        new List<DartType>.filled(a.typeArguments.length, null);
+        new List<DartType>.filled(a.typeArguments.length, dartTypeDummy);
     for (int i = 0; i < a.typeArguments.length; i++) {
-      DartType newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
+      DartType? newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
       if (newType == null) {
         return null;
       }
@@ -171,9 +168,9 @@
   }
 
   @override
-  DartType visitFutureOrType(FutureOrType a, DartType b) {
+  DartType? visitFutureOrType(FutureOrType a, DartType b) {
     if (b is FutureOrType) {
-      Nullability nullability = mergeNullability(a.nullability, b.nullability);
+      Nullability? nullability = mergeNullability(a.nullability, b.nullability);
       if (nullability != null) {
         return mergeFutureOrTypes(a, b, nullability);
       }
@@ -181,9 +178,9 @@
     return null;
   }
 
-  DartType mergeFutureOrTypes(
+  DartType? mergeFutureOrTypes(
       FutureOrType a, FutureOrType b, Nullability nullability) {
-    DartType newTypeArgument = a.typeArgument.accept1(this, b.typeArgument);
+    DartType? newTypeArgument = a.typeArgument.accept1(this, b.typeArgument);
     if (newTypeArgument == null) {
       return null;
     }
@@ -191,7 +188,7 @@
   }
 
   @override
-  DartType visitDynamicType(DynamicType a, DartType b) {
+  DartType? visitDynamicType(DynamicType a, DartType b) {
     if (b is DynamicType) {
       return a;
     }
@@ -199,9 +196,9 @@
   }
 
   @override
-  DartType visitNeverType(NeverType a, DartType b) {
+  DartType? visitNeverType(NeverType a, DartType b) {
     if (b is NeverType) {
-      Nullability nullability = mergeNullability(a.nullability, b.nullability);
+      Nullability? nullability = mergeNullability(a.nullability, b.nullability);
       if (nullability != null) {
         return NeverType.fromNullability(nullability);
       }
@@ -210,7 +207,7 @@
   }
 
   @override
-  DartType visitNullType(NullType a, DartType b) {
+  DartType? visitNullType(NullType a, DartType b) {
     if (b is NullType) {
       return a;
     }
@@ -218,13 +215,13 @@
   }
 
   @override
-  DartType visitInvalidType(InvalidType a, DartType b) => null;
+  DartType? visitInvalidType(InvalidType a, DartType b) => null;
 
   @override
-  DartType visitBottomType(BottomType a, DartType b) => null;
+  DartType? visitBottomType(BottomType a, DartType b) => null;
 
   @override
-  DartType visitVoidType(VoidType a, DartType b) {
+  DartType? visitVoidType(VoidType a, DartType b) {
     if (b is VoidType) {
       return a;
     }
@@ -232,9 +229,9 @@
   }
 
   @override
-  DartType visitTypeParameterType(TypeParameterType a, DartType b) {
+  DartType? visitTypeParameterType(TypeParameterType a, DartType b) {
     if (b is TypeParameterType && a.parameter == b.parameter) {
-      Nullability nullability =
+      Nullability? nullability =
           mergeNullability(a.declaredNullability, b.declaredNullability);
       if (nullability == null) {
         return null;
@@ -256,12 +253,12 @@
     return new TypeParameterType(a.parameter, nullability);
   }
 
-  DartType mergePromotedTypeParameterTypes(
+  DartType? mergePromotedTypeParameterTypes(
       TypeParameterType a, TypeParameterType b, Nullability nullability) {
     assert(a.parameter == b.parameter);
     assert(a.promotedBound != null);
     assert(b.promotedBound != null);
-    DartType newPromotedBound = a.promotedBound.accept1(this, b.promotedBound);
+    DartType? newPromotedBound = a.promotedBound.accept1(this, b.promotedBound);
     if (newPromotedBound == null) {
       return null;
     }
@@ -269,11 +266,11 @@
   }
 
   @override
-  DartType visitTypedefType(TypedefType a, DartType b) {
+  DartType? visitTypedefType(TypedefType a, DartType b) {
     if (b is TypedefType &&
         a.typedefNode == b.typedefNode &&
         a.typeArguments.length == b.typeArguments.length) {
-      Nullability nullability = mergeNullability(a.nullability, b.nullability);
+      Nullability? nullability = mergeNullability(a.nullability, b.nullability);
       if (nullability != null) {
         return mergeTypedefTypes(a, b, nullability);
       }
@@ -281,7 +278,7 @@
     return null;
   }
 
-  DartType mergeTypedefTypes(
+  DartType? mergeTypedefTypes(
       TypedefType a, TypedefType b, Nullability nullability) {
     assert(a.typedefNode == b.typedefNode);
     assert(a.typeArguments.length == b.typeArguments.length);
@@ -289,9 +286,9 @@
       return new TypedefType(a.typedefNode, nullability);
     }
     List<DartType> newTypeArguments =
-        new List<DartType>.filled(a.typeArguments.length, null);
+        new List<DartType>.filled(a.typeArguments.length, dartTypeDummy);
     for (int i = 0; i < a.typeArguments.length; i++) {
-      DartType newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
+      DartType? newType = a.typeArguments[i].accept1(this, b.typeArguments[i]);
       if (newType == null) return null;
       newTypeArguments[i] = newType;
     }
@@ -299,5 +296,5 @@
   }
 
   @override
-  DartType defaultDartType(DartType a, DartType b) => null;
+  DartType? defaultDartType(DartType a, DartType b) => null;
 }
diff --git a/pkg/kernel/lib/src/nnbd_top_merge.dart b/pkg/kernel/lib/src/nnbd_top_merge.dart
index fd5f9eb..7a81f62 100644
--- a/pkg/kernel/lib/src/nnbd_top_merge.dart
+++ b/pkg/kernel/lib/src/nnbd_top_merge.dart
@@ -2,8 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-// @dart = 2.9
-
+// ignore: import_of_legacy_library_into_null_safe
 import '../ast.dart' hide MapEntry;
 import '../core_types.dart';
 
@@ -11,15 +10,16 @@
 
 /// Returns the NNBD_TOP_MERGE of [a] and [b]. If [a] and [b] have no defined
 /// NNBD_TOP_MERGE `null` is returned.
-Supertype nnbdTopMergeSupertype(CoreTypes coreTypes, Supertype a, Supertype b) {
+Supertype? nnbdTopMergeSupertype(
+    CoreTypes coreTypes, Supertype a, Supertype b) {
   assert(a.classNode == b.classNode);
   if (a.typeArguments.isEmpty) {
     return a;
   }
   List<DartType> newTypeArguments =
-      new List<DartType>.filled(a.typeArguments.length, null);
+      new List<DartType>.filled(a.typeArguments.length, dartTypeDummy);
   for (int i = 0; i < a.typeArguments.length; i++) {
-    DartType newTypeArgument =
+    DartType? newTypeArgument =
         nnbdTopMerge(coreTypes, a.typeArguments[i], b.typeArguments[i]);
     if (newTypeArgument == null) return null;
     newTypeArguments[i] = newTypeArgument;
@@ -29,7 +29,7 @@
 
 /// Returns the NNBD_TOP_MERGE of [a] and [b]. If [a] and [b] have no defined
 /// NNBD_TOP_MERGE `null` is returned.
-DartType nnbdTopMerge(CoreTypes coreTypes, DartType a, DartType b) {
+DartType? nnbdTopMerge(CoreTypes coreTypes, DartType a, DartType b) {
   if (a == b) return a;
   return a.accept1(new NnbdTopMergeVisitor(coreTypes), b);
 }
@@ -40,7 +40,7 @@
   NnbdTopMergeVisitor(this.coreTypes);
 
   @override
-  Nullability mergeNullability(Nullability a, Nullability b) {
+  Nullability? mergeNullability(Nullability a, Nullability b) {
     if (a == b) {
       return a;
     } else if (a == Nullability.legacy) {
@@ -52,7 +52,7 @@
   }
 
   @override
-  DartType visitInterfaceType(InterfaceType a, DartType b) {
+  DartType? visitInterfaceType(InterfaceType a, DartType b) {
     if (a == coreTypes.objectNullableRawType) {
       if (b is DynamicType) {
         // NNBD_TOP_MERGE(Object?, dynamic) = Object?
@@ -77,7 +77,7 @@
   }
 
   @override
-  DartType visitVoidType(VoidType a, DartType b) {
+  DartType? visitVoidType(VoidType a, DartType b) {
     if (b is DynamicType) {
       // NNBD_TOP_MERGE(void, dynamic) = Object?
       return coreTypes.objectNullableRawType;
@@ -95,7 +95,7 @@
   }
 
   @override
-  DartType visitDynamicType(DynamicType a, DartType b) {
+  DartType? visitDynamicType(DynamicType a, DartType b) {
     if (b is DynamicType) {
       // NNBD_TOP_MERGE(dynamic, dynamic) = dynamic
       return const DynamicType();
@@ -113,7 +113,7 @@
   }
 
   @override
-  DartType visitNeverType(NeverType a, DartType b) {
+  DartType? visitNeverType(NeverType a, DartType b) {
     if (a.nullability == Nullability.legacy && b is NullType) {
       // NNBD_TOP_MERGE(Never*, Null) = Null
       return const NullType();
@@ -122,7 +122,7 @@
   }
 
   @override
-  DartType visitNullType(NullType a, DartType b) {
+  DartType? visitNullType(NullType a, DartType b) {
     if (b is NeverType && b.nullability == Nullability.legacy) {
       // NNBD_TOP_MERGE(Null, Never*) = Null
       return const NullType();
diff --git a/pkg/kernel/lib/src/norm.dart b/pkg/kernel/lib/src/norm.dart
index 9a39987..f828120 100644
--- a/pkg/kernel/lib/src/norm.dart
+++ b/pkg/kernel/lib/src/norm.dart
@@ -2,8 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-// @dart = 2.9
-
+// ignore: import_of_legacy_library_into_null_safe
 import '../ast.dart' hide MapEntry;
 import '../core_types.dart';
 import '../type_algebra.dart';
@@ -19,9 +18,9 @@
 Supertype normSupertype(CoreTypes coreTypes, Supertype supertype) {
   if (supertype.typeArguments.isEmpty) return supertype;
   _Norm normVisitor = new _Norm(coreTypes);
-  List<DartType> typeArguments = null;
+  List<DartType>? typeArguments = null;
   for (int i = 0; i < supertype.typeArguments.length; ++i) {
-    DartType typeArgument =
+    DartType? typeArgument =
         supertype.typeArguments[i].accept1(normVisitor, Variance.covariant);
     if (typeArgument != null) {
       typeArguments ??= supertype.typeArguments.toList();
@@ -43,7 +42,7 @@
   _Norm(this.coreTypes);
 
   @override
-  DartType visitInterfaceType(InterfaceType node, int variance) {
+  DartType? visitInterfaceType(InterfaceType node, int variance) {
     return super
         .visitInterfaceType(node, variance)
         ?.withDeclaredNullability(node.nullability);
@@ -87,11 +86,13 @@
     assert(!coreTypes.isObject(typeArgument));
     assert(!coreTypes.isBottom(typeArgument));
     assert(!coreTypes.isNull(typeArgument));
+    // TODO(johnniwinther): We should return `null` if [typeArgument] is
+    // the same as `node.typeArgument`.
     return new FutureOrType(typeArgument, node.nullability);
   }
 
   @override
-  DartType visitTypeParameterType(TypeParameterType node, int variance) {
+  DartType? visitTypeParameterType(TypeParameterType node, int variance) {
     if (node.promotedBound == null) {
       DartType bound = node.parameter.bound;
       if (normalizesToNever(bound)) {
@@ -133,7 +134,7 @@
   }
 
   @override
-  DartType visitNeverType(NeverType node, int variance) {
+  DartType? visitNeverType(NeverType node, int variance) {
     if (node.nullability == Nullability.nullable) return const NullType();
     return null;
   }
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index 1d5a8db..45e823e 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -4,7 +4,6 @@
 
 // ignore: import_of_legacy_library_into_null_safe
 import '../ast.dart' hide MapEntry;
-// ignore: import_of_legacy_library_into_null_safe
 import '../type_algebra.dart';
 
 /// Helper visitor that clones a type if a nested type is replaced, and
diff --git a/pkg/kernel/lib/src/standard_bounds.dart b/pkg/kernel/lib/src/standard_bounds.dart
index c8a1db4..efab942 100644
--- a/pkg/kernel/lib/src/standard_bounds.dart
+++ b/pkg/kernel/lib/src/standard_bounds.dart
@@ -2,29 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-// @dart = 2.9
-
 import 'dart:math' as math;
 
-import '../ast.dart'
-    show
-        BottomType,
-        Class,
-        DartType,
-        DynamicType,
-        FunctionType,
-        FutureOrType,
-        InterfaceType,
-        InvalidType,
-        Library,
-        NamedType,
-        NeverType,
-        NullType,
-        Nullability,
-        TypeParameter,
-        TypeParameterType,
-        Variance,
-        VoidType;
+// ignore: import_of_legacy_library_into_null_safe
+import '../ast.dart' hide MapEntry;
 import '../class_hierarchy.dart';
 import '../core_types.dart';
 import '../type_algebra.dart';
@@ -835,10 +816,12 @@
     // relation is established.
     InterfaceType typeWithoutNullabilityMarker1 =
         computeTypeWithoutNullabilityMarker(type1,
-            isNonNullableByDefault: clientLibrary.isNonNullableByDefault);
+                isNonNullableByDefault: clientLibrary.isNonNullableByDefault)
+            as InterfaceType;
     InterfaceType typeWithoutNullabilityMarker2 =
         computeTypeWithoutNullabilityMarker(type2,
-            isNonNullableByDefault: clientLibrary.isNonNullableByDefault);
+                isNonNullableByDefault: clientLibrary.isNonNullableByDefault)
+            as InterfaceType;
 
     if (isSubtypeOf(typeWithoutNullabilityMarker1,
         typeWithoutNullabilityMarker2, SubtypeCheckMode.withNullabilities)) {
@@ -861,7 +844,7 @@
         int n = klass.typeParameters.length;
         List<DartType> leftArguments = type1.typeArguments;
         List<DartType> rightArguments = type2.typeArguments;
-        List<DartType> typeArguments = new List<DartType>.filled(n, null);
+        List<DartType> typeArguments = new List<DartType>.from(leftArguments);
         for (int i = 0; i < n; ++i) {
           int variance = klass.typeParameters[i].variance;
           if (variance == Variance.contravariant) {
@@ -888,7 +871,8 @@
 
     // UP(C0<T0, ..., Tn>, C1<S0, ..., Sk>)
     //   = least upper bound of two interfaces as in Dart 1.
-    return hierarchy.getLegacyLeastUpperBound(type1, type2, clientLibrary);
+    return hierarchy.getLegacyLeastUpperBound(
+        type1 as InterfaceType, type2 as InterfaceType, clientLibrary);
   }
 
   /// Computes the nullability-aware lower bound of two function types.
@@ -983,7 +967,7 @@
     List<TypeParameter> typeParameters = f.typeParameters;
 
     List<DartType> positionalParameters =
-        new List<DartType>.filled(maxPos, null);
+        new List<DartType>.filled(maxPos, dartTypeDummy);
     for (int i = 0; i < minPos; ++i) {
       positionalParameters[i] = _getNullabilityAwareStandardUpperBound(
           f.positionalParameters[i],
@@ -1180,7 +1164,7 @@
     List<TypeParameter> typeParameters = f.typeParameters;
 
     List<DartType> positionalParameters =
-        new List<DartType>.filled(minPos, null);
+        new List<DartType>.filled(minPos, dartTypeDummy);
     for (int i = 0; i < minPos; ++i) {
       positionalParameters[i] = _getNullabilityAwareStandardLowerBound(
           f.positionalParameters[i],
@@ -1435,7 +1419,7 @@
     int totalPositional =
         math.max(f.positionalParameters.length, g.positionalParameters.length);
     List<DartType> positionalParameters =
-        new List<DartType>.filled(totalPositional, null);
+        new List<DartType>.filled(totalPositional, dartTypeDummy);
     for (int i = 0; i < totalPositional; i++) {
       if (i < f.positionalParameters.length) {
         DartType fType = f.positionalParameters[i];
@@ -1539,7 +1523,7 @@
     int totalPositional =
         math.min(f.positionalParameters.length, g.positionalParameters.length);
     List<DartType> positionalParameters =
-        new List<DartType>.filled(totalPositional, null);
+        new List<DartType>.filled(totalPositional, dartTypeDummy);
     for (int i = 0; i < totalPositional; i++) {
       positionalParameters[i] = getStandardLowerBound(
           f.positionalParameters[i], g.positionalParameters[i], clientLibrary);
@@ -1618,7 +1602,7 @@
 
       assert(tArgs1.length == tArgs2.length);
       assert(tArgs1.length == tParams.length);
-      List<DartType> tArgs = new List.filled(tArgs1.length, null);
+      List<DartType> tArgs = new List.filled(tArgs1.length, dartTypeDummy);
       for (int i = 0; i < tArgs1.length; i++) {
         if (tParams[i].variance == Variance.contravariant) {
           tArgs[i] = getStandardLowerBound(tArgs1[i], tArgs2[i], clientLibrary);
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index 4dcec69..b54c79d 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -2,8 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
+// ignore: import_of_legacy_library_into_null_safe
 import '../ast.dart'
     show
         BottomType,
@@ -53,7 +52,6 @@
       case SubtypeCheckMode.withNullabilities:
         return result.isSubtypeWhenUsingNullabilities();
     }
-    return throw new StateError("Unhandled subtype check mode '$mode'.");
   }
 
   bool _isSubtypeFromMode(IsSubtypeOf isSubtypeOf, SubtypeCheckMode mode) {
@@ -86,8 +84,8 @@
     IsSubtypeOf result = const IsSubtypeOf.always();
     //result = _performNullabilityAwareSubtypeCheck(subtype, supertype, mode);
     bool booleanResult = _isSubtypeFromMode(result, mode);
-    typeChecksForTesting ??= <Object>[];
-    typeChecksForTesting.add([subtype, supertype, booleanResult]);
+    (typeChecksForTesting ??= <Object>[])
+        .add([subtype, supertype, booleanResult]);
     return booleanResult;
   }
 
@@ -315,14 +313,14 @@
     return result;
   }
 
-  static List<Object> typeChecksForTesting;
+  static List<Object>? typeChecksForTesting;
 
-  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass,
+  InterfaceType? getTypeAsInstanceOf(InterfaceType type, Class superclass,
       Library clientLibrary, CoreTypes coreTypes) {
     return hierarchy.getTypeAsInstanceOf(type, superclass, clientLibrary);
   }
 
-  List<DartType> getTypeArgumentsAsInstanceOf(
+  List<DartType>? getTypeArgumentsAsInstanceOf(
       InterfaceType type, Class superclass) {
     return hierarchy.getTypeArgumentsAsInstanceOf(type, superclass);
   }
@@ -368,7 +366,7 @@
   @override
   IsSubtypeOf isInterfaceRelated(
       InterfaceType s, InterfaceType t, Types types) {
-    List<DartType> asSupertypeArguments =
+    List<DartType>? asSupertypeArguments =
         types.hierarchy.getTypeArgumentsAsInstanceOf(s, t.classNode);
     if (asSupertypeArguments == null) {
       return const IsSubtypeOf.never();
@@ -477,7 +475,7 @@
           }
         }
       }
-      s = substitution.substituteType(s.withoutTypeParameters);
+      s = substitution.substituteType(s.withoutTypeParameters) as FunctionType;
     }
     result = result.and(
         types.performNullabilityAwareSubtypeCheck(s.returnType, t.returnType));
@@ -520,7 +518,7 @@
       for (int tCount = 0; tCount < tNamedParameters.length; tCount++) {
         NamedType tNamedParameter = tNamedParameters[tCount];
         String name = tNamedParameter.name;
-        NamedType sNamedParameter;
+        NamedType? sNamedParameter;
         for (; sCount < sNamedParameters.length; sCount++) {
           sNamedParameter = sNamedParameters[sCount];
           if (sNamedParameter.name == name) {
@@ -538,7 +536,7 @@
         // loop above or below and assume it is an extra (unmatched) parameter.
         sCount++;
         result = result.and(types.performNullabilityAwareSubtypeCheck(
-            tNamedParameter.type, sNamedParameter.type));
+            tNamedParameter.type, sNamedParameter!.type));
         if (!result.isSubtypeWhenIgnoringNullabilities()) {
           return const IsSubtypeOf.never();
         }
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 96d0aef..18c4924 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -2,10 +2,9 @@
 // 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.type_algebra;
 
+// ignore: import_of_legacy_library_into_null_safe
 import 'ast.dart';
 import 'core_types.dart';
 import 'src/replacement_visitor.dart';
@@ -63,7 +62,7 @@
 ///
 /// As with [substitute], this is guaranteed to return the same instance if no
 /// substitution was performed.
-DartType substituteDeep(
+DartType? substituteDeep(
     DartType type, Map<TypeParameter, DartType> substitution) {
   if (substitution.isEmpty) return type;
   _DeepTypeSubstitutor substitutor = new _DeepTypeSubstitutor(substitution);
@@ -82,7 +81,7 @@
 /// It is an error to call this with a [type] that contains a [FunctionType]
 /// that declares one of the parameters in [variables].
 bool containsTypeVariable(DartType type, Set<TypeParameter> variables,
-    {bool Function(DartType type, bool Function(DartType type) recursor)
+    {bool Function(DartType type, bool Function(DartType type) recursor)?
         unhandledTypeHandler}) {
   if (variables.isEmpty) return false;
   return new _OccurrenceVisitor(variables,
@@ -141,15 +140,16 @@
 
   FreshTypeParameters(this.freshTypeParameters, this.substitution);
 
-  FunctionType applyToFunctionType(FunctionType type) => new FunctionType(
-      type.positionalParameters.map(substitute).toList(),
-      substitute(type.returnType),
-      type.nullability,
-      namedParameters: type.namedParameters.map(substituteNamed).toList(),
-      typeParameters: freshTypeParameters,
-      requiredParameterCount: type.requiredParameterCount,
-      typedefType:
-          type.typedefType == null ? null : substitute(type.typedefType));
+  FunctionType applyToFunctionType(FunctionType type) {
+    return new FunctionType(type.positionalParameters.map(substitute).toList(),
+        substitute(type.returnType), type.nullability,
+        namedParameters: type.namedParameters.map(substituteNamed).toList(),
+        typeParameters: freshTypeParameters,
+        requiredParameterCount: type.requiredParameterCount,
+        typedefType: type.typedefType == null
+            ? null
+            : substitute(type.typedefType) as TypedefType);
+  }
 
   DartType substitute(DartType type) => substitution.substituteType(type);
 
@@ -269,7 +269,8 @@
     return new _CombinedSubstitution(first, second);
   }
 
-  DartType getSubstitute(TypeParameter parameter, bool upperBound);
+  /// Returns the substitution for [parameter]
+  DartType? getSubstitute(TypeParameter parameter, bool upperBound);
 
   DartType substituteType(DartType node, {bool contravariant: false}) {
     return new _TopSubstitutor(this, contravariant).visit(node);
@@ -305,7 +306,7 @@
 
   _MapSubstitution(this.upper, this.lower);
 
-  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+  DartType? getSubstitute(TypeParameter parameter, bool upperBound) {
     return upperBound ? upper[parameter] : lower[parameter];
   }
 
@@ -322,7 +323,7 @@
     }
   }
 
-  DartType lookup(TypeParameter parameter, bool upperBound) {
+  DartType? lookup(TypeParameter parameter, bool upperBound) {
     return substitution.getSubstitute(parameter, upperBound);
   }
 
@@ -336,7 +337,7 @@
 
   _ClassBottomSubstitution(this.class_);
 
-  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+  DartType? getSubstitute(TypeParameter parameter, bool upperBound) {
     if (parameter.parent == class_) {
       return upperBound ? const BottomType() : const DynamicType();
     }
@@ -349,7 +350,7 @@
 
   _CombinedSubstitution(this.first, this.second);
 
-  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+  DartType? getSubstitute(TypeParameter parameter, bool upperBound) {
     return first.getSubstitute(parameter, upperBound) ??
         second.getSubstitute(parameter, upperBound);
   }
@@ -363,7 +364,7 @@
 
   _FilteredSubstitution(this.base, this.filterFn);
 
-  DartType getSubstitute(TypeParameter parameter, bool upperBound) {
+  DartType? getSubstitute(TypeParameter parameter, bool upperBound) {
     return filterFn(parameter)
         ? base.getSubstitute(parameter, upperBound)
         : _NullSubstitution.instance.getSubstitute(parameter, upperBound);
@@ -373,9 +374,9 @@
 class _InnerTypeSubstitutor extends _TypeSubstitutor {
   final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
 
-  _InnerTypeSubstitutor(_TypeSubstitutor outer) : super(outer);
+  _InnerTypeSubstitutor(_TypeSubstitutor? outer) : super(outer);
 
-  DartType lookup(TypeParameter parameter, bool upperBound) {
+  DartType? lookup(TypeParameter parameter, bool upperBound) {
     return substitution[parameter];
   }
 
@@ -445,14 +446,13 @@
 }
 
 abstract class _TypeSubstitutor extends DartTypeVisitor<DartType> {
-  final _TypeSubstitutor outer;
+  final _TypeSubstitutor? outer;
   bool covariantContext = true;
 
-  _TypeSubstitutor(this.outer) {
-    covariantContext = outer == null ? true : outer.covariantContext;
-  }
+  _TypeSubstitutor(this.outer)
+      : covariantContext = outer == null ? true : outer.covariantContext;
 
-  DartType lookup(TypeParameter parameter, bool upperBound);
+  DartType? lookup(TypeParameter parameter, bool upperBound);
 
   /// The number of times a variable from this environment has been used in
   /// a substitution.
@@ -559,8 +559,9 @@
         : node.namedParameters.map(inner.visitNamedType).toList();
     inner.invertVariance();
     DartType returnType = inner.visit(node.returnType);
-    DartType typedefType =
-        node.typedefType == null ? null : inner.visit(node.typedefType);
+    TypedefType? typedefType = node.typedefType == null
+        ? null
+        : inner.visit(node.typedefType) as TypedefType;
     if (this.useCounter == before) return node;
     return new FunctionType(positionalParameters, returnType, node.nullability,
         namedParameters: namedParameters,
@@ -570,18 +571,18 @@
   }
 
   void bumpCountersUntil(_TypeSubstitutor target) {
-    _TypeSubstitutor node = this;
+    _TypeSubstitutor? node = this;
     while (node != target) {
-      ++node.useCounter;
+      ++node!.useCounter;
       node = node.outer;
     }
     ++target.useCounter;
   }
 
-  DartType getSubstitute(TypeParameter variable) {
-    _TypeSubstitutor environment = this;
+  DartType? getSubstitute(TypeParameter variable) {
+    _TypeSubstitutor? environment = this;
     while (environment != null) {
-      DartType replacement = environment.lookup(variable, covariantContext);
+      DartType? replacement = environment.lookup(variable, covariantContext);
       if (replacement != null) {
         bumpCountersUntil(environment);
         return replacement;
@@ -592,7 +593,7 @@
   }
 
   DartType visitTypeParameterType(TypeParameterType node) {
-    DartType replacement = getSubstitute(node.parameter);
+    DartType? replacement = getSubstitute(node.parameter);
     if (replacement is InvalidType) return replacement;
     if (replacement != null) {
       return replacement.withDeclaredNullability(
@@ -608,7 +609,7 @@
   bool isInfinite = false;
 
   _DeepTypeSubstitutor(Map<TypeParameter, DartType> substitution,
-      [_DeepTypeSubstitutor outer])
+      [_DeepTypeSubstitutor? outer])
       : super(outer) {
     this.substitution.addAll(substitution);
   }
@@ -620,7 +621,7 @@
 
   @override
   DartType visitTypeParameterType(TypeParameterType node) {
-    DartType replacement = getSubstitute(node.parameter);
+    DartType? replacement = getSubstitute(node.parameter);
     if (replacement == null) return node;
     if (isInfinite) return replacement;
     ++depth;
@@ -647,7 +648,7 @@
   /// from within the handler on parts of the unknown type to recursively call
   /// the visitor.  If not set, an exception is thrown then an unhandled
   /// implementer of [DartType] is encountered.
-  final bool Function(DartType node, bool Function(DartType node) recursor)
+  final bool Function(DartType node, bool Function(DartType node) recursor)?
       unhandledTypeHandler;
 
   _OccurrenceVisitor(this.variables, {this.unhandledTypeHandler});
@@ -662,7 +663,7 @@
     if (unhandledTypeHandler == null) {
       throw new UnsupportedError("Unsupported type '${node.runtimeType}'.");
     } else {
-      return unhandledTypeHandler(node, visit);
+      return unhandledTypeHandler!(node, visit);
     }
   }
 
@@ -693,7 +694,7 @@
   }
 
   bool visitTypeParameterType(TypeParameterType node) {
-    return variables == null || variables.contains(node.parameter);
+    return variables.contains(node.parameter);
   }
 
   bool handleTypeParameter(TypeParameter node) {
@@ -848,8 +849,7 @@
 /// are the base cases of the recursion.  According to the visitor a primitive
 /// type is any [DartType] that doesn't include other [DartType]s as its parts.
 /// The nullability attributes don't affect the primitiveness of a type.
-bool isPrimitiveDartType(DartType type,
-    {bool Function(DartType unhandledType) unhandledTypeHandler}) {
+bool isPrimitiveDartType(DartType type) {
   return type.accept(const _PrimitiveTypeVerifier());
 }
 
@@ -1000,49 +1000,53 @@
   final DartType topType;
   final DartType topFunctionType;
   final Set<TypeParameter> eliminationTargets;
-  bool isLeastClosure;
-  bool Function(DartType type, bool Function(DartType type) recursor)
-      unhandledTypeHandler; // Can be null.
+  late bool _isLeastClosure;
+  final bool Function(DartType type, bool Function(DartType type) recursor)?
+      unhandledTypeHandler;
 
   NullabilityAwareTypeVariableEliminator(
-      {this.eliminationTargets,
-      this.bottomType,
-      this.topType,
-      this.topFunctionType,
+      {required this.eliminationTargets,
+      required this.bottomType,
+      required this.topType,
+      required this.topFunctionType,
       this.unhandledTypeHandler})
+      // ignore: unnecessary_null_comparison
       : assert(eliminationTargets != null),
+        // ignore: unnecessary_null_comparison
         assert(bottomType != null),
+        // ignore: unnecessary_null_comparison
         assert(topType != null),
+        // ignore: unnecessary_null_comparison
         assert(topFunctionType != null);
 
   /// Returns a subtype of [type] for all values of [eliminationTargets].
   DartType eliminateToLeast(DartType type) {
-    isLeastClosure = true;
+    _isLeastClosure = true;
     return type.accept1(this, Variance.covariant) ?? type;
   }
 
   /// Returns a supertype of [type] for all values of [eliminationTargets].
   DartType eliminateToGreatest(DartType type) {
-    isLeastClosure = false;
+    _isLeastClosure = false;
     return type.accept1(this, Variance.covariant) ?? type;
   }
 
   DartType getTypeParameterReplacement(int variance) {
     bool isCovariant = variance == Variance.covariant;
-    return isLeastClosure && isCovariant || (!isLeastClosure && !isCovariant)
+    return _isLeastClosure && isCovariant || (!_isLeastClosure && !isCovariant)
         ? bottomType
         : topType;
   }
 
   DartType getFunctionReplacement(int variance) {
     bool isCovariant = variance == Variance.covariant;
-    return isLeastClosure && isCovariant || (!isLeastClosure && !isCovariant)
+    return _isLeastClosure && isCovariant || (!_isLeastClosure && !isCovariant)
         ? bottomType
         : topFunctionType;
   }
 
   @override
-  DartType visitFunctionType(FunctionType node, int variance) {
+  DartType? visitFunctionType(FunctionType node, int variance) {
     // - if `S` is
     //   `T Function<X0 extends B0, ...., Xk extends Bk>(T0 x0, ...., Tn xn,
     //       [Tn+1 xn+1, ..., Tm xm])`
@@ -1063,7 +1067,7 @@
   }
 
   @override
-  DartType visitTypeParameterType(TypeParameterType node, int variance) {
+  DartType? visitTypeParameterType(TypeParameterType node, int variance) {
     if (eliminationTargets.contains(node.parameter)) {
       return getTypeParameterReplacement(variance);
     }
@@ -1080,7 +1084,8 @@
 /// [TypeParameterType]s, the result may be either [Nullability.nonNullable] or
 /// [Nullability.undetermined], depending on the bound.
 DartType computeTypeWithoutNullabilityMarker(DartType type,
-    {bool isNonNullableByDefault}) {
+    {required bool isNonNullableByDefault}) {
+  // ignore: unnecessary_null_comparison
   assert(isNonNullableByDefault != null);
 
   if (type is TypeParameterType) {
@@ -1112,7 +1117,8 @@
 /// are T% and S, where T and S are type parameters such that T extends Object?
 /// and S extends Object.
 bool isTypeParameterTypeWithoutNullabilityMarker(TypeParameterType type,
-    {bool isNonNullableByDefault}) {
+    {required bool isNonNullableByDefault}) {
+  // ignore: unnecessary_null_comparison
   assert(isNonNullableByDefault != null);
 
   // The default nullability for library is used when there are no nullability
@@ -1124,7 +1130,8 @@
 }
 
 bool isTypeWithoutNullabilityMarker(DartType type,
-    {bool isNonNullableByDefault}) {
+    {required bool isNonNullableByDefault}) {
+  // ignore: unnecessary_null_comparison
   assert(isNonNullableByDefault != null);
   return !type.accept(new _NullabilityMarkerDetector(isNonNullableByDefault));
 }
@@ -1223,7 +1230,8 @@
 /// declared within a legacy library and is not one of exempt types, such as
 /// dynamic or void.
 bool isLegacyTypeConstructorApplication(DartType type,
-    {bool isNonNullableByDefault}) {
+    {required bool isNonNullableByDefault}) {
+  // ignore: unnecessary_null_comparison
   assert(isNonNullableByDefault != null);
 
   if (type is TypeParameterType) {
@@ -1241,7 +1249,8 @@
 }
 
 Nullability _defaultNullabilityForTypeParameterType(TypeParameter parameter,
-    {bool isNonNullableByDefault}) {
+    {required bool isNonNullableByDefault}) {
+  // ignore: unnecessary_null_comparison
   assert(isNonNullableByDefault != null);
   return isNonNullableByDefault
       ? TypeParameterType.computeNullabilityFromBound(parameter)
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
index 4b993f5..da45c08 100644
--- a/pkg/kernel/lib/type_environment.dart
+++ b/pkg/kernel/lib/type_environment.dart
@@ -2,15 +2,13 @@
 // 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.type_environment;
 
-import 'package:kernel/type_algebra.dart';
-
+// ignore: import_of_legacy_library_into_null_safe
 import 'ast.dart';
 import 'class_hierarchy.dart';
 import 'core_types.dart';
+import 'type_algebra.dart';
 
 import 'src/hierarchy_based_type_environment.dart'
     show HierarchyBasedTypeEnvironment;
@@ -21,10 +19,6 @@
 abstract class TypeEnvironment extends Types {
   final CoreTypes coreTypes;
 
-  /// An error handler for use in debugging, or `null` if type errors should not
-  /// be tolerated.  See [typeError].
-  ErrorHandler errorHandler;
-
   TypeEnvironment.fromSubclass(this.coreTypes, ClassHierarchyBase base)
       : super(base);
 
@@ -105,7 +99,7 @@
     //   and for all R, if T <: Future<R> then S <: R; then flatten(T) = S
     DartType resolved = _resolveTypeParameterType(t);
     if (resolved is InterfaceType) {
-      List<DartType> futureArguments =
+      List<DartType>? futureArguments =
           getTypeArgumentsAsInstanceOf(resolved, coreTypes.futureClass);
       if (futureArguments != null) {
         return _withDeclaredNullability(
@@ -128,22 +122,24 @@
   }
 
   /// Returns the type of the element in the for-in statement [node] with
-  /// [iterableType] as the static type of the iterable expression.
+  /// [iterableExpressionType] as the static type of the iterable expression.
   ///
-  /// The [iterableType] must be a subclass of `Stream` or `Iterable` depending
-  /// on whether `node.isAsync` is `true` or not.
-  DartType forInElementType(ForInStatement node, DartType iterableType) {
+  /// The [iterableExpressionType] must be a subclass of `Stream` or `Iterable`
+  /// depending on whether `node.isAsync` is `true` or not.
+  DartType forInElementType(
+      ForInStatement node, DartType iterableExpressionType) {
     // TODO(johnniwinther): Update this to use the type of
     //  `iterable.iterator.current` if inference is updated accordingly.
-    iterableType = _resolveTypeParameterType(iterableType);
+    InterfaceType iterableType =
+        _resolveTypeParameterType(iterableExpressionType) as InterfaceType;
     if (node.isAsync) {
-      List<DartType> typeArguments =
+      List<DartType>? typeArguments =
           getTypeArgumentsAsInstanceOf(iterableType, coreTypes.streamClass);
-      return typeArguments.single;
+      return typeArguments!.single;
     } else {
-      List<DartType> typeArguments =
+      List<DartType>? typeArguments =
           getTypeArgumentsAsInstanceOf(iterableType, coreTypes.iterableClass);
-      return typeArguments.single;
+      return typeArguments!.single;
     }
   }
 
@@ -301,7 +297,7 @@
   ///
   /// If multiple members with that name are inherited and not overridden, the
   /// member from the first declared supertype is returned.
-  Member getInterfaceMember(Class cls, Name name, {bool setter: false});
+  Member? getInterfaceMember(Class cls, Name name, {bool setter: false});
 }
 
 /// Tri-state logical result of a nullability-aware subtype check.
@@ -322,7 +318,9 @@
   static const List<IsSubtypeOf> _all = const <IsSubtypeOf>[
     const IsSubtypeOf.never(),
     const IsSubtypeOf.onlyIfIgnoringNullabilities(),
-    null, // Deliberately left empty because there's no index value for that.
+    // There's no value for this index so we use `IsSubtypeOf.never()` as a
+    // dummy value.
+    const IsSubtypeOf.never(),
     const IsSubtypeOf.always()
   ];
 
@@ -347,9 +345,9 @@
   /// The only state of an [IsSubtypeOf] object.
   final int _value;
 
-  final DartType subtype;
+  final DartType? subtype;
 
-  final DartType supertype;
+  final DartType? supertype;
 
   const IsSubtypeOf._internal(int value, this.subtype, this.supertype)
       : _value = value;
@@ -366,7 +364,7 @@
   /// nullability markers are ignored, it should also fail for those types in
   /// full-NNBD mode.
   const IsSubtypeOf.onlyIfIgnoringNullabilities(
-      {DartType subtype, DartType supertype})
+      {DartType? subtype, DartType? supertype})
       : this._internal(_valueOnlyIfIgnoringNullabilities, subtype, supertype);
 
   /// Subtype check fails in both modes.
@@ -407,11 +405,10 @@
         DartType unwrappedSubtype = subtype;
         DartType unwrappedSupertype = supertype;
         while (unwrappedSubtype is FutureOrType) {
-          unwrappedSubtype = (unwrappedSubtype as FutureOrType).typeArgument;
+          unwrappedSubtype = unwrappedSubtype.typeArgument;
         }
         while (unwrappedSupertype is FutureOrType) {
-          unwrappedSupertype =
-              (unwrappedSupertype as FutureOrType).typeArgument;
+          unwrappedSupertype = unwrappedSupertype.typeArgument;
         }
         if (unwrappedSubtype.nullability == unwrappedSupertype.nullability) {
           // The relationship between the types must be established elsewhere.
@@ -541,23 +538,20 @@
 }
 
 class StaticTypeCacheImpl implements StaticTypeCache {
-  Map<Expression, DartType> _expressionTypes;
-  Map<ForInStatement, DartType> _forInIteratorTypes;
-  Map<ForInStatement, DartType> _forInElementTypes;
+  late Map<Expression, DartType> _expressionTypes = {};
+  late Map<ForInStatement, DartType> _forInIteratorTypes = {};
+  late Map<ForInStatement, DartType> _forInElementTypes = {};
 
   DartType getExpressionType(Expression node, StaticTypeContext context) {
-    _expressionTypes ??= <Expression, DartType>{};
     return _expressionTypes[node] ??= node.getStaticTypeInternal(context);
   }
 
   DartType getForInIteratorType(
       ForInStatement node, StaticTypeContext context) {
-    _forInIteratorTypes ??= <ForInStatement, DartType>{};
     return _forInIteratorTypes[node] ??= node.getIteratorTypeInternal(context);
   }
 
   DartType getForInElementType(ForInStatement node, StaticTypeContext context) {
-    _forInElementTypes ??= <ForInStatement, DartType>{};
     return _forInElementTypes[node] ??= node.getElementTypeInternal(context);
   }
 }
@@ -574,7 +568,7 @@
   TypeEnvironment get typeEnvironment;
 
   /// The static type of a `this` expression.
-  InterfaceType get thisType;
+  InterfaceType? get thisType;
 
   /// Creates a static type context for computing static types in the body
   /// of [member].
@@ -627,14 +621,14 @@
   final Library _library;
 
   /// The static type of a `this` expression.
-  final InterfaceType thisType;
+  final InterfaceType? thisType;
 
-  final StaticTypeCache _cache;
+  final StaticTypeCache? _cache;
 
   /// Creates a static type context for computing static types in the body
   /// of [member].
   StaticTypeContextImpl(Member member, this.typeEnvironment,
-      {StaticTypeCache cache})
+      {StaticTypeCache? cache})
       : _library = member.enclosingLibrary,
         thisType = member.enclosingClass?.getThisType(
             typeEnvironment.coreTypes, member.enclosingLibrary.nonNullable),
@@ -643,7 +637,7 @@
   /// Creates a static type context for computing static types of annotations
   /// in [library].
   StaticTypeContextImpl.forAnnotations(this._library, this.typeEnvironment,
-      {StaticTypeCache cache})
+      {StaticTypeCache? cache})
       : thisType = null,
         _cache = cache;
 
@@ -667,7 +661,7 @@
 
   DartType getExpressionType(Expression node) {
     if (_cache != null) {
-      return _cache.getExpressionType(node, this);
+      return _cache!.getExpressionType(node, this);
     } else {
       return node.getStaticTypeInternal(this);
     }
@@ -675,7 +669,7 @@
 
   DartType getForInIteratorType(ForInStatement node) {
     if (_cache != null) {
-      return _cache.getForInIteratorType(node, this);
+      return _cache!.getForInIteratorType(node, this);
     } else {
       return node.getIteratorTypeInternal(this);
     }
@@ -683,7 +677,7 @@
 
   DartType getForInElementType(ForInStatement node) {
     if (_cache != null) {
-      return _cache.getForInElementType(node, this);
+      return _cache!.getForInElementType(node, this);
     } else {
       return node.getElementTypeInternal(this);
     }
@@ -738,32 +732,33 @@
 /// Implementation of [StatefulStaticTypeContext] that only supports entering
 /// one library and/or at a time.
 class _FlatStatefulStaticTypeContext extends StatefulStaticTypeContext {
-  Library _currentLibrary;
-  Member _currentMember;
+  Library? _currentLibrary;
+  Member? _currentMember;
 
   _FlatStatefulStaticTypeContext(TypeEnvironment typeEnvironment)
       : super._internal(typeEnvironment);
 
   Library get _library {
-    Library library = _currentLibrary ?? _currentMember?.enclosingLibrary;
+    Library? library = _currentLibrary ?? _currentMember?.enclosingLibrary;
     assert(library != null,
         "No library currently associated with StaticTypeContext.");
-    return library;
+    return library!;
   }
 
   @override
-  InterfaceType get thisType {
+  InterfaceType? get thisType {
     assert(_currentMember != null,
         "No member currently associated with StaticTypeContext.");
     return _currentMember?.enclosingClass?.getThisType(
-        typeEnvironment.coreTypes, _currentMember.enclosingLibrary.nonNullable);
+        typeEnvironment.coreTypes,
+        _currentMember?.enclosingLibrary.nonNullable);
   }
 
   @override
-  Nullability get nonNullable => _library?.nonNullable;
+  Nullability get nonNullable => _library.nonNullable;
 
   @override
-  Nullability get nullable => _library?.nullable;
+  Nullability get nullable => _library.nullable;
 
   @override
   bool get isNonNullableByDefault => _library.isNonNullableByDefault;
@@ -855,20 +850,20 @@
   }
 
   @override
-  InterfaceType get thisType {
+  InterfaceType? get thisType {
     assert(_contextStack.isNotEmpty,
         "No this type currently associated with StaticTypeContext.");
     return _contextStack.last._thisType;
   }
 
   @override
-  Nullability get nonNullable => _library?.nonNullable;
+  Nullability get nonNullable => _library.nonNullable;
 
   @override
-  Nullability get nullable => _library?.nullable;
+  Nullability get nullable => _library.nullable;
 
   @override
-  bool get isNonNullableByDefault => _library?.isNonNullableByDefault;
+  bool get isNonNullableByDefault => _library.isNonNullableByDefault;
 
   @override
   NonNullableByDefaultCompiledMode get nonNullableByDefaultCompiledMode =>
@@ -940,7 +935,7 @@
 class _StaticTypeContextState {
   final TreeNode _node;
   final Library _library;
-  final InterfaceType _thisType;
+  final InterfaceType? _thisType;
 
   _StaticTypeContextState(this._node, this._library, this._thisType);
 }
diff --git a/pkg/test_runner/lib/src/android.dart b/pkg/test_runner/lib/src/android.dart
index aa8fa5c..0797ea6 100644
--- a/pkg/test_runner/lib/src/android.dart
+++ b/pkg/test_runner/lib/src/android.dart
@@ -344,7 +344,7 @@
 /// Helper to list all adb devices available.
 class AdbHelper {
   static final RegExp _deviceLineRegexp =
-      RegExp(r'^([a-zA-Z0-9_-]+)[ \t]+device$', multiLine: true);
+      RegExp(r'^([a-zA-Z0-9:_-]+)[ \t]+device$', multiLine: true);
 
   static Future<List<String>> listDevices() {
     return Process.run('adb', ['devices']).then((ProcessResult result) {
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index 2bdbc86..8f5f98b 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1467,29 +1467,29 @@
   __ CompareImmediate(R1, kDoubleCid);
   __ b(&not_double, NE);
 
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::double_type_offset());
   __ Ret();
 
   __ Bind(&not_double);
   JumpIfNotInteger(assembler, R1, R0, &not_integer);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::int_type_offset());
   __ Ret();
 
   __ Bind(&not_integer);
   JumpIfNotString(assembler, R1, R0, &not_string);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::string_type_offset());
   __ Ret();
 
   __ Bind(&not_string);
   JumpIfNotType(assembler, R1, R0, &use_declaration_type);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::type_type_offset());
   __ Ret();
 
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 8b3fbd2..c2adf98 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1537,29 +1537,29 @@
   __ CompareImmediate(R1, kDoubleCid);
   __ b(&not_double, NE);
 
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::double_type_offset());
   __ ret();
 
   __ Bind(&not_double);
   JumpIfNotInteger(assembler, R1, R0, &not_integer);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::int_type_offset());
   __ ret();
 
   __ Bind(&not_integer);
   JumpIfNotString(assembler, R1, R0, &not_string);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::string_type_offset());
   __ ret();
 
   __ Bind(&not_string);
   JumpIfNotType(assembler, R1, R0, &use_declaration_type);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, target::Isolate::cached_object_store_offset());
+  __ LoadIsolateGroup(R0);
+  __ LoadFromOffset(R0, R0, target::IsolateGroup::object_store_offset());
   __ LoadFromOffset(R0, R0, target::ObjectStore::type_type_offset());
   __ ret();
 
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 89f488c..b06895c 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1559,8 +1559,8 @@
   __ cmpl(EDI, Immediate(kDoubleCid));
   __ j(NOT_EQUAL, &not_double);
 
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(EAX);
+  __ movl(EAX, Address(EAX, target::IsolateGroup::object_store_offset()));
   __ movl(EAX, Address(EAX, target::ObjectStore::double_type_offset()));
   __ ret();
 
@@ -1569,8 +1569,8 @@
   __ movl(EAX, EDI);
   JumpIfNotInteger(assembler, EAX, &not_integer);
 
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(EAX);
+  __ movl(EAX, Address(EAX, target::IsolateGroup::object_store_offset()));
   __ movl(EAX, Address(EAX, target::ObjectStore::int_type_offset()));
   __ ret();
 
@@ -1580,8 +1580,8 @@
   __ movl(EAX, EDI);
   JumpIfNotString(assembler, EAX, &not_string);
 
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(EAX);
+  __ movl(EAX, Address(EAX, target::IsolateGroup::object_store_offset()));
   __ movl(EAX, Address(EAX, target::ObjectStore::string_type_offset()));
   __ ret();
 
@@ -1590,8 +1590,8 @@
   __ movl(EAX, EDI);
   JumpIfNotType(assembler, EAX, &use_declaration_type);
 
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(EAX);
+  __ movl(EAX, Address(EAX, target::IsolateGroup::object_store_offset()));
   __ movl(EAX, Address(EAX, target::ObjectStore::type_type_offset()));
   __ ret();
 
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index bcfbd8e..8cf9a76 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1465,8 +1465,8 @@
   __ cmpl(RCX, Immediate(kDoubleCid));
   __ j(NOT_EQUAL, &not_double);
 
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(RAX);
+  __ movq(RAX, Address(RAX, target::IsolateGroup::object_store_offset()));
   __ movq(RAX, Address(RAX, target::ObjectStore::double_type_offset()));
   __ ret();
 
@@ -1475,8 +1475,8 @@
   __ movl(RAX, RCX);
   JumpIfNotInteger(assembler, RAX, &not_integer);
 
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(RAX);
+  __ movq(RAX, Address(RAX, target::IsolateGroup::object_store_offset()));
   __ movq(RAX, Address(RAX, target::ObjectStore::int_type_offset()));
   __ ret();
 
@@ -1486,8 +1486,8 @@
   __ movq(RAX, RCX);
   JumpIfNotString(assembler, RAX, &not_string);
 
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(RAX);
+  __ movq(RAX, Address(RAX, target::IsolateGroup::object_store_offset()));
   __ movq(RAX, Address(RAX, target::ObjectStore::string_type_offset()));
   __ ret();
 
@@ -1496,8 +1496,8 @@
   __ movq(RAX, RCX);
   JumpIfNotType(assembler, RAX, &use_declaration_type);
 
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, target::Isolate::cached_object_store_offset()));
+  __ LoadIsolateGroup(RAX);
+  __ movq(RAX, Address(RAX, target::IsolateGroup::object_store_offset()));
   __ movq(RAX, Address(RAX, target::ObjectStore::type_type_offset()));
   __ ret();
 
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 2160708..e1772e2 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -1147,7 +1147,6 @@
 
 class Isolate : public AllStatic {
  public:
-  static word cached_object_store_offset();
   static word default_tag_offset();
   static word current_tag_offset();
   static word user_tag_offset();
@@ -1159,6 +1158,7 @@
 
 class IsolateGroup : public AllStatic {
  public:
+  static word object_store_offset();
   static word shared_class_table_offset();
   static word cached_class_table_table_offset();
 };
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 94dc8ed..d5794ad 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -168,13 +168,13 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 32;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    20;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 8;
 static constexpr dart::compiler::target::word
     IsolateGroup_cached_class_table_table_offset = 16;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 40;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 36;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -701,13 +701,13 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     IsolateGroup_cached_class_table_table_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 80;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 72;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -1239,13 +1239,13 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 32;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    20;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 8;
 static constexpr dart::compiler::target::word
     IsolateGroup_cached_class_table_table_offset = 16;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 40;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 36;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 16;
 static constexpr dart::compiler::target::word
@@ -1769,13 +1769,13 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     IsolateGroup_cached_class_table_table_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 80;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 72;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -2310,13 +2310,13 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     IsolateGroup_cached_class_table_table_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 80;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 72;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -2850,13 +2850,13 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     IsolateGroup_cached_class_table_table_offset = 32;
-static constexpr dart::compiler::target::word Isolate_single_step_offset = 80;
+static constexpr dart::compiler::target::word Isolate_single_step_offset = 72;
 static constexpr dart::compiler::target::word Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word LinkedHashMap_data_offset = 32;
 static constexpr dart::compiler::target::word
@@ -3389,8 +3389,8 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 32;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    20;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 8;
 static constexpr dart::compiler::target::word
@@ -3916,8 +3916,8 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
@@ -4448,8 +4448,8 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 20;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 24;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 28;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 32;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    20;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 8;
 static constexpr dart::compiler::target::word
@@ -4972,8 +4972,8 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
@@ -5507,8 +5507,8 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
@@ -6041,8 +6041,8 @@
 static constexpr dart::compiler::target::word Isolate_current_tag_offset = 40;
 static constexpr dart::compiler::target::word Isolate_default_tag_offset = 48;
 static constexpr dart::compiler::target::word Isolate_ic_miss_code_offset = 56;
-static constexpr dart::compiler::target::word
-    Isolate_cached_object_store_offset = 64;
+static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
+    40;
 static constexpr dart::compiler::target::word
     IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
@@ -6588,13 +6588,13 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     28;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 32;
+    AOT_IsolateGroup_object_store_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_cached_class_table_table_offset = 16;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    40;
+    36;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 16;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     16;
@@ -7182,13 +7182,13 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_cached_class_table_table_offset = 32;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -7782,13 +7782,13 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_cached_class_table_table_offset = 32;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -8380,13 +8380,13 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_cached_class_table_table_offset = 32;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -8977,13 +8977,13 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_cached_class_table_table_offset = 32;
 static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset =
-    80;
+    72;
 static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 32;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_data_offset =
     32;
@@ -9574,7 +9574,7 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     28;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 32;
+    AOT_IsolateGroup_object_store_offset = 20;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 8;
 static constexpr dart::compiler::target::word
@@ -10161,7 +10161,7 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
@@ -10754,7 +10754,7 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
@@ -11345,7 +11345,7 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
@@ -11935,7 +11935,7 @@
 static constexpr dart::compiler::target::word AOT_Isolate_ic_miss_code_offset =
     56;
 static constexpr dart::compiler::target::word
-    AOT_Isolate_cached_object_store_offset = 64;
+    AOT_IsolateGroup_object_store_offset = 40;
 static constexpr dart::compiler::target::word
     AOT_IsolateGroup_shared_class_table_offset = 16;
 static constexpr dart::compiler::target::word
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 3a0da0f..2008f3f 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -130,7 +130,7 @@
   FIELD(Isolate, current_tag_offset)                                           \
   FIELD(Isolate, default_tag_offset)                                           \
   FIELD(Isolate, ic_miss_code_offset)                                          \
-  FIELD(Isolate, cached_object_store_offset)                                   \
+  FIELD(IsolateGroup, object_store_offset)                                     \
   FIELD(IsolateGroup, shared_class_table_offset)                               \
   FIELD(IsolateGroup, cached_class_table_table_offset)                         \
   NOT_IN_PRODUCT(FIELD(Isolate, single_step_offset))                           \
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 51a197c..05300a9 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -295,10 +295,8 @@
     StackZone zone(T);
     HandleScope handle_scope(T);
     Object::InitNullAndBool(vm_isolate_->group());
-    vm_isolate_->set_object_store(new ObjectStore());
+    vm_isolate_->isolate_group_->set_object_store(new ObjectStore());
     vm_isolate_->isolate_object_store()->Init();
-    vm_isolate_->isolate_group_->object_store_ =
-        vm_isolate_->object_store_shared_ptr_;
     TargetCPUFeatures::Init();
     Object::Init(vm_isolate_->group());
     ArgumentsDescriptor::Init();
@@ -942,7 +940,9 @@
       return error.ptr();
     }
   }
-  error ^= I->isolate_object_store()->PreallocateObjects();
+  const auto& out_of_memory =
+      Object::Handle(IG->object_store()->out_of_memory());
+  error ^= I->isolate_object_store()->PreallocateObjects(out_of_memory);
   if (!error.IsNull()) {
     return error.ptr();
   }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f781823..d5603cc 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -335,6 +335,7 @@
     : shared_class_table_(new SharedClassTable()),
       class_table_(new ClassTable(shared_class_table_.get())),
       cached_class_table_table_(class_table_->table()),
+      object_store_(object_store),
       embedder_data_(embedder_data),
       thread_pool_(),
       isolates_lock_(new SafepointRwLock()),
@@ -350,7 +351,6 @@
       api_state_(new ApiState()),
       thread_registry_(new ThreadRegistry()),
       safepoint_handler_(new SafepointHandler(this)),
-      object_store_(object_store),
       store_buffer_(new StoreBuffer()),
       heap_(nullptr),
       saved_unlinked_calls_(Array::null()),
@@ -1018,11 +1018,8 @@
       writer.WriteMessage(msg, main_port(), Message::kOOBPriority));
 }
 
-void Isolate::set_object_store(ObjectStore* object_store) {
-  ASSERT(cached_object_store_ == nullptr);
-  object_store_shared_ptr_.reset(object_store);
-  cached_object_store_ = object_store;
-  isolate_object_store_->set_object_store(object_store);
+void IsolateGroup::set_object_store(ObjectStore* object_store) {
+  object_store_.reset(object_store);
 }
 
 class IsolateMessageHandler : public MessageHandler {
@@ -1710,9 +1707,7 @@
       ic_miss_code_(Code::null()),
       field_table_(new FieldTable(/*isolate=*/this)),
       isolate_group_(isolate_group),
-      isolate_object_store_(
-          new IsolateObjectStore(isolate_group->object_store())),
-      object_store_shared_ptr_(isolate_group->object_store_shared_ptr()),
+      isolate_object_store_(new IsolateObjectStore()),
 #if !defined(DART_PRECOMPILED_RUNTIME)
       native_callback_trampolines_(),
 #endif
@@ -1726,7 +1721,7 @@
       ISOLATE_METRIC_LIST(ISOLATE_METRIC_CONSTRUCTORS)
 #undef ISOLATE_METRIC_CONSTRUCTORS
 #endif  // !defined(PRODUCT)
-      start_time_micros_(OS::GetCurrentMonotonicMicros()),
+          start_time_micros_(OS::GetCurrentMonotonicMicros()),
       on_shutdown_callback_(Isolate::ShutdownCallback()),
       on_cleanup_callback_(Isolate::CleanupCallback()),
       random_(),
@@ -1738,7 +1733,6 @@
       handler_info_cache_(),
       catch_entry_moves_cache_(),
       loaded_prefixes_set_storage_(nullptr) {
-  cached_object_store_ = object_store_shared_ptr_.get();
   FlagsCopyFrom(api_flags);
   SetErrorsFatal(true);
   // TODO(asiva): A Thread is not available here, need to figure out
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 809af6a..d3a0ba6 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -450,6 +450,12 @@
     return OFFSET_OF(IsolateGroup, cached_class_table_table_);
   }
 
+  void set_object_store(ObjectStore* object_store);
+  static intptr_t object_store_offset() {
+    COMPILE_ASSERT(sizeof(IsolateGroup::object_store_) == kWordSize);
+    return OFFSET_OF(IsolateGroup, object_store_);
+  }
+
   void set_obfuscation_map(const char** map) { obfuscation_map_ = map; }
   const char** obfuscation_map() const { return obfuscation_map_; }
 
@@ -833,14 +839,11 @@
 
   void set_heap(std::unique_ptr<Heap> value);
 
-  const std::shared_ptr<ObjectStore>& object_store_shared_ptr() const {
-    return object_store_;
-  }
-
   // Accessed from generated code.
   std::unique_ptr<SharedClassTable> shared_class_table_;
   std::unique_ptr<ClassTable> class_table_;
   AcqRelAtomic<ClassPtr*> cached_class_table_table_;
+  std::unique_ptr<ObjectStore> object_store_;
   // End accessed from generated code.
 
   const char** obfuscation_map_ = nullptr;
@@ -895,7 +898,6 @@
 
   uint64_t id_ = 0;
 
-  std::shared_ptr<ObjectStore> object_store_;
   std::unique_ptr<StoreBuffer> store_buffer_;
   std::unique_ptr<Heap> heap_;
   std::unique_ptr<DispatchTable> dispatch_table_;
@@ -1004,11 +1006,6 @@
     return group()->safepoint_handler();
   }
 
-  void set_object_store(ObjectStore* object_store);
-  static intptr_t cached_object_store_offset() {
-    return OFFSET_OF(Isolate, cached_object_store_);
-  }
-
   FieldTable* field_table() const { return field_table_; }
   void set_field_table(Thread* T, FieldTable* field_table) {
     delete field_table_;
@@ -1537,8 +1534,6 @@
   UserTagPtr current_tag_;
   UserTagPtr default_tag_;
   CodePtr ic_miss_code_;
-  // Cached value of object_store_shared_ptr_, here for generated code access
-  ObjectStore* cached_object_store_ = nullptr;
   FieldTable* field_table_ = nullptr;
   bool single_step_ = false;
   bool is_system_isolate_ = false;
@@ -1547,8 +1542,6 @@
   IsolateGroup* isolate_group_;
   IdleTimeHandler idle_time_handler_;
   std::unique_ptr<IsolateObjectStore> isolate_object_store_;
-  // shared in AOT(same pointer as on IsolateGroup), not shared in JIT
-  std::shared_ptr<ObjectStore> object_store_shared_ptr_;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   NativeCallbackTrampolines native_callback_trampolines_;
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 76c15da..feb4803 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -16,11 +16,6 @@
 
 namespace dart {
 
-IsolateObjectStore::IsolateObjectStore(ObjectStore* object_store)
-    : object_store_(object_store) {}
-
-IsolateObjectStore::~IsolateObjectStore() {}
-
 void IsolateObjectStore::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(visitor != NULL);
   visitor->set_gc_root_type("isolate_object store");
@@ -68,7 +63,7 @@
   return stack_trace.ptr();
 }
 
-ErrorPtr IsolateObjectStore::PreallocateObjects() {
+ErrorPtr IsolateObjectStore::PreallocateObjects(const Object& out_of_memory) {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
@@ -80,8 +75,6 @@
 
   // Allocate pre-allocated unhandled exception object initialized with the
   // pre-allocated OutOfMemoryError.
-  const Object& out_of_memory =
-      Object::Handle(zone, object_store_->out_of_memory());
   const StackTrace& preallocated_stack_trace =
       StackTrace::Handle(zone, CreatePreallocatedStackTrace(zone));
   set_preallocated_stack_trace(preallocated_stack_trace);
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 3642e50..7554f4d 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -312,8 +312,8 @@
 
 class IsolateObjectStore {
  public:
-  explicit IsolateObjectStore(ObjectStore* object_store);
-  ~IsolateObjectStore();
+  IsolateObjectStore() {}
+  ~IsolateObjectStore() {}
 
 #define DECLARE_GETTER(Type, name)                                             \
   Type##Ptr name() const { return name##_; }                                   \
@@ -334,21 +334,11 @@
   // Called to initialize objects required by the vm but which invoke
   // dart code.  If an error occurs the error object is returned otherwise
   // a null object is returned.
-  ErrorPtr PreallocateObjects();
+  ErrorPtr PreallocateObjects(const Object& out_of_memory);
 
   void Init();
   void PostLoad();
 
-  ObjectStore* object_store() const { return object_store_; }
-  void set_object_store(ObjectStore* object_store) {
-    ASSERT(object_store_ == nullptr);
-    object_store_ = object_store;
-  }
-
-  static intptr_t object_store_offset() {
-    return OFFSET_OF(IsolateObjectStore, object_store_);
-  }
-
 #ifndef PRODUCT
   void PrintToJSONObject(JSONObject* jsobj);
 #endif
@@ -366,8 +356,6 @@
 #undef DECLARE_OBJECT_STORE_FIELD
   ObjectPtr* to() { return reinterpret_cast<ObjectPtr*>(&error_listeners_); }
 
-  ObjectStore* object_store_;
-
   friend class Serializer;
   friend class Deserializer;
 
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 0d1539d..33df08e 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -5,8 +5,16 @@
 /// Support for asynchronous programming,
 /// with classes such as Future and Stream.
 ///
-/// Understanding [Future]s and [Stream]s is a prerequisite for
-/// writing just about any Dart program.
+/// [Future]s and [Stream]s are the fundamental building blocks
+/// of asynchronous programming in Dart. They are supported
+/// directly in the language through `async` and `async*`
+/// functions, and are available to all libraries through
+/// the `dart:core` library.
+///
+/// This library provides further tools for creating, consuming
+/// and transforming futures and streams, as well as direct access to
+/// other asynchronous primitives like [timers][Timer],
+/// [microtasks][scheduleMicrotask] and [zones][Zone].
 ///
 /// To use this library in your code:
 /// ```dart
@@ -21,8 +29,8 @@
 /// Futures are often used for potentially lengthy computations
 /// such as I/O and interaction with users.
 ///
-/// Many methods in the Dart libraries return Futures when
-/// performing tasks. For example, when binding an HttpServer
+/// Many methods in the Dart libraries return `Future`s when
+/// performing tasks. For example, when binding an `HttpServer`
 /// to a host and port, the `bind()` method returns a Future.
 /// ```dart
 ///  HttpServer.bind('127.0.0.1', 4444)
@@ -47,14 +55,17 @@
 /// contents of a file
 /// such as mouse clicks, and a stream of byte lists read from a file.
 /// The following example opens a file for reading.
-/// [Stream.listen] registers a callback function that runs
-/// each time more data is available.
+/// [Stream.listen] registers callback functions that run
+/// each time more data is available, an error has occurred, or
+/// the stream has finished.
+/// Further functionality is provided on [Stream], implemented by calling
+/// [Stream.listen] to get the actual data.
 /// ```dart
 /// Stream<List<int>> stream = File('quotes.txt').openRead();
-/// stream.transform(utf8.decoder).listen(print);
+/// stream.transform(utf8.decoder).forEach(print);
 /// ```
-/// The stream emits a sequence of a list of bytes.
-/// The program must interpret the bytes or handle the raw byte data.
+/// This stream emits a sequence of lists of bytes.
+/// The program must then handle those lists of bytes in some way.
 /// Here, the code uses a UTF-8 decoder (provided in the `dart:convert` library)
 /// to convert the sequence of bytes into a sequence
 /// of Dart strings.
@@ -62,7 +73,7 @@
 /// Another common use of streams is for user-generated events
 /// in a web app: The following code listens for mouse clicks on a button.
 /// ```dart
-/// querySelector('#myButton').onClick.listen((_) => print('Click.'));
+/// querySelector('#myButton').onClick.forEach((_) => print('Click.'));
 /// ```
 /// ## Other resources
 ///
diff --git a/sdk/lib/ffi/struct.dart b/sdk/lib/ffi/struct.dart
index 37fa93c..283d04c 100644
--- a/sdk/lib/ffi/struct.dart
+++ b/sdk/lib/ffi/struct.dart
@@ -58,10 +58,3 @@
 
   Struct._fromPointer(this._addressOf);
 }
-
-/// Extension on [Struct] specialized for its subtypes.
-extension StructAddressOf<T extends Struct> on T {
-  /// Returns the address backing the reference.
-  @Deprecated('Hold on to the pointer backing a struct instead.')
-  Pointer<T> get addressOf => _addressOf as Pointer<T>;
-}
diff --git a/tests/ffi/structs_nnbd_workaround_test.dart b/tests/ffi/structs_nnbd_workaround_test.dart
index cf8f672..635c877 100644
--- a/tests/ffi/structs_nnbd_workaround_test.dart
+++ b/tests/ffi/structs_nnbd_workaround_test.dart
@@ -98,8 +98,6 @@
   final pointer = calloc<Coordinate>();
   Coordinate c = pointer.ref;
   Expect.isTrue(c is Struct);
-  // TODO(https://dartbug.com/40667): Remove support for this.
-  Expect.isTrue(c.addressOf is Pointer<Coordinate>);
   calloc.free(pointer);
 }
 
diff --git a/tests/ffi/structs_test.dart b/tests/ffi/structs_test.dart
index 77026a4..ba90416 100644
--- a/tests/ffi/structs_test.dart
+++ b/tests/ffi/structs_test.dart
@@ -128,8 +128,6 @@
   final pointer = calloc<Coordinate>();
   Coordinate c = pointer.ref;
   Expect.isTrue(c is Struct);
-  // TODO(https://dartbug.com/40667): Remove support for this.
-  Expect.isTrue(c.addressOf is Pointer<Coordinate>);
   calloc.free(pointer);
 }
 
diff --git a/tests/ffi_2/structs_test.dart b/tests/ffi_2/structs_test.dart
index 77026a4..ba90416 100644
--- a/tests/ffi_2/structs_test.dart
+++ b/tests/ffi_2/structs_test.dart
@@ -128,8 +128,6 @@
   final pointer = calloc<Coordinate>();
   Coordinate c = pointer.ref;
   Expect.isTrue(c is Struct);
-  // TODO(https://dartbug.com/40667): Remove support for this.
-  Expect.isTrue(c.addressOf is Pointer<Coordinate>);
   calloc.free(pointer);
 }
 
diff --git a/tools/VERSION b/tools/VERSION
index f57edce..12c6833 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 30
+PRERELEASE 31
 PRERELEASE_PATCH 0
\ No newline at end of file