Version 2.14.0-21.0.dev

Merge commit '69d56fd82a11a61588b55887471c5523079edcc5' into 'dev'
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 0134b77..128aa38 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -848,8 +848,6 @@
   StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
   StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
   StaticWarningCode.UNNECESSARY_NON_NULL_ASSERTION,
-  StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE,
-  StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
   TodoCode.TODO,
 ];
 
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 9900a5e..bef21eb 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -14180,63 +14180,3 @@
   @override
   ErrorType get type => ErrorType.STATIC_WARNING;
 }
-
-/**
- * This class has Strong Mode specific error codes.
- *
- * "Strong Mode" was the prototype for Dart 2's sound type system. Many of these
- * errors became part of Dart 2. Some of them are optional flags, used for
- * stricter checking.
- *
- * These error codes tend to use the same message across different severity
- * levels, so they are grouped for clarity.
- */
-class StrongModeCode extends ErrorCode {
-  /*
-   * TODO(brianwilkerson) Make the TOP_LEVEL_ error codes be errors rather than
-   * hints and then clean up the function _errorSeverity in
-   * test/src/task/strong/strong_test_helper.dart.
-   */
-  /* TODO(leafp) Delete most of these.
-   */
-
-  static const StrongModeCode TOP_LEVEL_IDENTIFIER_NO_TYPE = StrongModeCode(
-      ErrorType.HINT,
-      'TOP_LEVEL_IDENTIFIER_NO_TYPE',
-      "The type of '{0}' can't be inferred because the type of '{1}' "
-          "couldn't be inferred.",
-      correction:
-          "Try adding an explicit type to either the variable '{0}' or the "
-          "variable '{1}'.");
-
-  static const StrongModeCode TOP_LEVEL_INSTANCE_GETTER = StrongModeCode(
-      ErrorType.STATIC_WARNING,
-      'TOP_LEVEL_INSTANCE_GETTER',
-      "The type of '{0}' can't be inferred because it refers to an instance "
-          "getter, '{1}', which has an implicit type.",
-      correction: "Add an explicit type for either '{0}' or '{1}'.");
-
-  @override
-  final ErrorType type;
-
-  /**
-   * Initialize a newly created error code to have the given [type] and [name].
-   *
-   * The message associated with the error will be created from the given
-   * [message] template. The correction associated with the error will be
-   * created from the optional [correction] template.
-   */
-  const StrongModeCode(ErrorType type, String name, String message,
-      {String? correction, bool hasPublishedDocs = false})
-      : type = type,
-        super(
-          correction: correction,
-          hasPublishedDocs: hasPublishedDocs,
-          message: message,
-          name: name,
-          uniqueName: 'StrongModeCode.$name',
-        );
-
-  @override
-  ErrorSeverity get errorSeverity => type.severity;
-}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 4138d99..9f51dba 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -376,15 +376,6 @@
     return _node.name.name;
   }
 
-  bool get isImplicitlyTypedInstanceField {
-    var variables = _node.parent as VariableDeclarationList;
-    if (variables.type == null) {
-      var parent = variables.parent;
-      return parent is FieldDeclaration && !parent.isStatic;
-    }
-    return false;
-  }
-
   PropertyInducingElementImpl get _elementImpl {
     return _node.declaredElement as PropertyInducingElementImpl;
   }
@@ -400,19 +391,7 @@
       return const <_InferenceNode>[];
     }
 
-    var dependencies =
-        collector._set.map(_walker.getNode).whereNotNull().toList();
-
-    for (var node in dependencies) {
-      if (node is _VariableInferenceNode &&
-          node.isImplicitlyTypedInstanceField) {
-        _elementImpl.type = DynamicTypeImpl.instance;
-        isEvaluated = true;
-        return const <_InferenceNode>[];
-      }
-    }
-
-    return dependencies;
+    return collector._set.map(_walker.getNode).whereNotNull().toList();
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index bd2547c..3d179d7 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -17,8 +17,7 @@
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/error/codes.dart'
-    show CompileTimeErrorCode, StrongModeCode;
+import 'package:analyzer/src/error/codes.dart' show CompileTimeErrorCode;
 import 'package:analyzer/src/task/inference_error.dart';
 
 Element? _getKnownElement(Expression expression) {
@@ -497,14 +496,21 @@
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
-    var variableElement = node.declaredElement;
-    var parent = node.parent;
-    if (variableElement is PropertyInducingElement &&
-        parent is VariableDeclarationList &&
-        parent.type == null) {
-      var initializer = node.initializer;
-      if (initializer != null) {
-        _validateTopLevelInitializer(variableElement.name, initializer);
+    var element = node.declaredElement;
+    if (element is PropertyInducingElementImpl) {
+      var error = element.typeInferenceError;
+      if (error != null) {
+        if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
+          // Errors on const should have been reported with
+          // [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT].
+          if (!element.isConst) {
+            _recordMessage(
+              node.name,
+              CompileTimeErrorCode.TOP_LEVEL_CYCLE,
+              [element.name, error.arguments],
+            );
+          }
+        }
       }
     }
     node.visitChildren(this);
@@ -916,10 +922,6 @@
     reporter.onError(error);
   }
 
-  void _validateTopLevelInitializer(String name, Expression n) {
-    n.accept(_TopLevelInitializerValidator(this, name));
-  }
-
   void _visitForEachParts(ForEachParts node, SimpleIdentifier loopVariable) {
     if (loopVariable.staticElement is! VariableElement) {
       return;
@@ -983,169 +985,3 @@
     throw StateError('${e.runtimeType} is unhandled type');
   }
 }
-
-class _TopLevelInitializerValidator extends RecursiveAstVisitor<void> {
-  final CodeChecker _codeChecker;
-  final String _name;
-
-  _TopLevelInitializerValidator(this._codeChecker, this._name);
-
-  void validateHasType(AstNode n, PropertyAccessorElement e) {
-    if (e.hasImplicitReturnType) {
-      var variable = e.declaration.variable as PropertyInducingElementImpl;
-      var error = variable.typeInferenceError;
-      if (error != null) {
-        if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
-          // Errors on const should have been reported with
-          // [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT].
-          if (!variable.isConst) {
-            _codeChecker._recordMessage(n, CompileTimeErrorCode.TOP_LEVEL_CYCLE,
-                [_name, error.arguments]);
-          }
-        } else {
-          _codeChecker._recordMessage(
-              n, StrongModeCode.TOP_LEVEL_IDENTIFIER_NO_TYPE, [_name, e.name]);
-        }
-      }
-    }
-  }
-
-  void validateIdentifierElement(AstNode n, Element? e,
-      {bool isMethodCall = false}) {
-    if (e == null) {
-      return;
-    }
-
-    var enclosing = e.enclosingElement;
-    if (enclosing is CompilationUnitElement) {
-      if (e is PropertyAccessorElement) {
-        validateHasType(n, e);
-      }
-    } else if (enclosing is ClassElement) {
-      if (e is PropertyAccessorElement) {
-        if (e.isStatic) {
-          validateHasType(n, e);
-        } else if (e.hasImplicitReturnType) {
-          _codeChecker._recordMessage(
-              n, StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, [_name, e.name]);
-        }
-      }
-    }
-  }
-
-  @override
-  visitAsExpression(AsExpression node) {
-    // Nothing to validate.
-  }
-
-  @override
-  visitBinaryExpression(BinaryExpression node) {
-    TokenType operator = node.operator.type;
-    if (operator == TokenType.AMPERSAND_AMPERSAND ||
-        operator == TokenType.BAR_BAR ||
-        operator == TokenType.EQ_EQ ||
-        operator == TokenType.BANG_EQ) {
-      // These operators give 'bool', no need to validate operands.
-    } else {
-      node.leftOperand.accept(this);
-    }
-  }
-
-  @override
-  visitCascadeExpression(CascadeExpression node) {
-    node.target.accept(this);
-  }
-
-  @override
-  visitConditionalExpression(ConditionalExpression node) {
-    // No need to validate the condition, since it can't affect type inference.
-    node.thenExpression.accept(this);
-    node.elseExpression.accept(this);
-  }
-
-  @override
-  visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    if (node.typeArguments != null) {
-      return;
-    }
-
-    var function = node.function;
-    if (function is PropertyAccess) {
-      var propertyName = function.propertyName;
-      validateIdentifierElement(propertyName, propertyName.staticElement);
-    }
-
-    var functionType = node.function.staticType;
-    if (functionType is FunctionType && functionType.typeFormals.isNotEmpty) {
-      node.argumentList.accept(this);
-    }
-  }
-
-  @override
-  visitIndexExpression(IndexExpression node) {
-    // Nothing to validate.
-  }
-
-  @override
-  visitInstanceCreationExpression(InstanceCreationExpression node) {
-    var constructor = node.constructorName.staticElement;
-    var class_ = constructor?.enclosingElement;
-    if (node.constructorName.type.typeArguments == null &&
-        class_ != null &&
-        class_.typeParameters.isNotEmpty) {
-      // Type inference might depend on the parameters
-      super.visitInstanceCreationExpression(node);
-    }
-  }
-
-  @override
-  visitIsExpression(IsExpression node) {
-    // Nothing to validate.
-  }
-
-  @override
-  visitListLiteral(ListLiteral node) {
-    if (node.typeArguments == null) {
-      super.visitListLiteral(node);
-    }
-  }
-
-  @override
-  visitMethodInvocation(MethodInvocation node) {
-    node.target?.accept(this);
-    var method = node.methodName.staticElement;
-    validateIdentifierElement(node, method, isMethodCall: true);
-    if (method is ExecutableElement) {
-      if (node.typeArguments == null && method.typeParameters.isNotEmpty) {
-        // Type inference might depend on the parameters
-        node.argumentList.accept(this);
-      }
-    }
-  }
-
-  @override
-  visitPrefixExpression(PrefixExpression node) {
-    if (node.operator.type == TokenType.BANG) {
-      // This operator gives 'bool', no need to validate operands.
-    } else {
-      node.operand.accept(this);
-    }
-  }
-
-  @override
-  visitSetOrMapLiteral(SetOrMapLiteral node) {
-    if (node.typeArguments == null) {
-      super.visitSetOrMapLiteral(node);
-    }
-  }
-
-  @override
-  visitSimpleIdentifier(SimpleIdentifier node) {
-    validateIdentifierElement(node, node.staticElement);
-  }
-
-  @override
-  visitThrowExpression(ThrowExpression node) {
-    // Nothing to validate.
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 77fa53c..85e16c6 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -34,7 +34,8 @@
 }
 final b = new A().a;
 ''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 49, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 18, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 37, 1),
     ]);
 
     assertTypeDynamic(findElement.field('a').type);
diff --git a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
index c3b6d67..52e2b7c 100644
--- a/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implicit_this_reference_in_initializer_test.dart
@@ -93,7 +93,6 @@
   final y = x;
 }
 ''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 37, 1),
       error(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, 37, 1),
     ]);
   }
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
index 0f72b33..fbe9053 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_cycle_test.dart
@@ -20,8 +20,8 @@
 var x = y + 1;
 var y = x + 1;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 23, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 19, 1),
     ]);
   }
 
@@ -29,7 +29,7 @@
     await assertErrorsInCode(r'''
 var x = x;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
     ]);
   }
 
@@ -41,7 +41,7 @@
   ],
 ];
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 25, 5),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 5),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
index 8153be9..3a78473 100644
--- a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/context_collection_resolution.dart';
@@ -82,81 +81,71 @@
   }
 
   test_implicitlyTyped() async {
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   get g => 0;
 }
 var b = new A().g;
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 42, 1),
-    ]);
+''');
+    assertTypeDynamic(findElement.topVar('b').type);
   }
 
   test_implicitlyTyped_call() async {
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   get g => () => 0;
 }
 var a = new A();
 var b = a.g();
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 59, 1),
-    ]);
+''');
+    assertTypeDynamic(findElement.topVar('b').type);
   }
 
   test_implicitlyTyped_field() async {
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var g = 0;
 }
 var b = new A().g;
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 41, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_field_call() async {
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var g = () => 0;
 }
 var a = new A();
 var b = a.g();
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 58, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_field_prefixedIdentifier() async {
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var g = 0;
 }
 var a = new A();
 var b = a.g;
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 52, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_fn() async {
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
-    // generic, so the type of a.x might affect the type of b.
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var x = 0;
 }
 int f<T>(x) => 0;
 var a = new A();
 var b = f(a.x);
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 72, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_fn_explicit_type_params() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -165,11 +154,10 @@
 var a = new A();
 var b = f<int>(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_fn_not_generic() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -178,11 +166,10 @@
 var a = new A();
 var b = f(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_indexExpression() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -191,25 +178,21 @@
 var a = new A();
 var b = a[a.x];
 ''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_invoke() async {
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the
-    // closure is generic, so the type of a.x might affect the type of b.
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var x = 0;
 }
 var a = new A();
 var b = (<T>(y) => 0)(a.x);
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 66, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_invoke_explicit_type_params() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -217,11 +200,10 @@
 var a = new A();
 var b = (<T>(y) => 0)<int>(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_invoke_not_generic() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -229,26 +211,22 @@
 var a = new A();
 var b = ((y) => 0)(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_method() async {
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
-    // generic, so the type of a.x might affect the type of b.
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var x = 0;
   int f<T>(int x) => 0;
 }
 var a = new A();
 var b = a.f(a.x);
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 80, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_method_explicit_type_params() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -257,11 +235,10 @@
 var a = new A();
 var b = a.f<int>(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_method_not_generic() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -270,28 +247,24 @@
 var a = new A();
 var b = a.f(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_implicitlyTyped_new() async {
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
-    // generic, so the type of a.x might affect the type of b.
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var x = 0;
 }
 class B<T> {
-  B(x);
+  B(T x);
 }
 var a = new A();
 var b = new B(a.x);
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 81, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_explicit_type_params() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -302,11 +275,10 @@
 var a = new A();
 var b = new B<int>(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_explicit_type_params_named() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -317,11 +289,10 @@
 var a = new A();
 var b = new B<int>.named(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_explicit_type_params_prefixed() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     newFile('$testPackageLibPath/lib1.dart', content: '''
 class B<T> {
   B(x);
@@ -335,28 +306,24 @@
 var a = new A();
 var b = new foo.B<int>(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_named() async {
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
-    // generic, so the type of a.x might affect the type of b.
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var x = 0;
 }
 class B<T> {
-  B.named(x);
+  B.named(T x);
 }
 var a = new A();
 var b = new B.named(a.x);
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 93, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_new_not_generic() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -367,11 +334,10 @@
 var a = new A();
 var b = new B(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'B');
   }
 
   test_implicitlyTyped_new_not_generic_named() async {
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 class A {
   var x = 0;
@@ -382,6 +348,7 @@
 var a = new A();
 var b = new B.named(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'B');
   }
 
   test_implicitlyTyped_new_not_generic_prefixed() async {
@@ -390,8 +357,6 @@
   B(x);
 }
 ''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
     await assertNoErrorsInCode('''
 import 'lib1.dart' as foo;
 class A {
@@ -400,44 +365,39 @@
 var a = new A();
 var b = new foo.B(a.x);
 ''');
+    assertType(findElement.topVar('b').type, 'B');
   }
 
   test_implicitlyTyped_new_prefixed() async {
     newFile('$testPackageLibPath/lib1.dart', content: '''
 class B<T> {
-  B(x);
+  B(T x);
 }
 ''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
-    // generic, so the type of a.x might affect the type of b.
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 import 'lib1.dart' as foo;
 class A {
   var x = 0;
 }
 var a = new A();
 var b = new foo.B(a.x);
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 89, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'B<int>');
   }
 
   test_implicitlyTyped_prefixedIdentifier() async {
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   get g => 0;
 }
 var a = new A();
 var b = a.g;
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 53, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'dynamic');
   }
 
   test_implicitlyTyped_propertyAccessLhs() async {
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the type
-    // of a.x affects the lookup of y, which in turn affects the type of b.
-    await assertErrorsInCode('''
+    await assertNoErrorsInCode('''
 class A {
   var x = new B();
   int operator[](int value) => 0;
@@ -447,9 +407,8 @@
 }
 var a = new A();
 var b = (a.x).y;
-''', [
-      error(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, 118, 1),
-    ]);
+''');
+    assertType(findElement.topVar('b').type, 'int');
   }
 
   test_prefixedIdentifier() async {
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index 5675f3f..d7828d1 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -101,8 +101,8 @@
 var a = b;
 var b = a;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 8, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 19, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 15, 1),
     ]);
   }
 
@@ -718,7 +718,7 @@
 class C {
   int f;
 }
-dynamic x;
+int x;
 ''');
   }
 
@@ -735,7 +735,7 @@
 ''');
     checkElementText(library, r'''
 import 'package:test/a.dart';
-dynamic x;
+int x;
 ''');
   }
 
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index d77818f..d20ec18 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -364,8 +364,8 @@
 var x = () => y;
 var y = () => x;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 14, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 31, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 21, 1),
     ]);
 
     var x = _resultUnitElement.topLevelVariables[0];
@@ -381,8 +381,8 @@
 var x = () => y;
 var y = () => x;
 ''', [
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 14, 1),
-      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 31, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 4, 1),
+      error(CompileTimeErrorCode.TOP_LEVEL_CYCLE, 21, 1),
     ]);
 
     var x = _resultUnitElement.topLevelVariables[0];
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index ba03221..93ee6da 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -101,7 +101,7 @@
     bool needsPostUpdate = false;
     Nullability nullability;
     if (nullabilityBuilder.isOmitted) {
-      if (parameter.bound != null) {
+      if (!identical(parameter.bound, TypeParameter.unsetBoundSentinel)) {
         nullability = library.isNonNullableByDefault
             ? TypeParameterType.computeNullabilityFromBound(parameter)
             : Nullability.legacy;
@@ -154,7 +154,9 @@
     // TODO(jensj): Provide correct notInstanceContext.
     DartType objectType =
         object.buildType(library, library.nullableBuilder, null, null);
-    parameter.bound ??= bound?.build(library) ?? objectType;
+    if (identical(parameter.bound, TypeParameter.unsetBoundSentinel)) {
+      parameter.bound = bound?.build(library) ?? objectType;
+    }
     // If defaultType is not set, initialize it to dynamic, unless the bound is
     // explicitly specified as Object, in which case defaultType should also be
     // Object. This makes sure instantiation of generic function types with an
diff --git a/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
index 2a81180..be667a7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
@@ -79,7 +79,7 @@
   bool visitFunctionType(FunctionType node, Set<TypedefType> visitedTypedefs) {
     if (node.returnType.accept1(this, visitedTypedefs)) return true;
     for (TypeParameter typeParameter in node.typeParameters) {
-      if (typeParameter.bound!.accept1(this, visitedTypedefs)) return true;
+      if (typeParameter.bound.accept1(this, visitedTypedefs)) return true;
       // TODO(dmitryas): Check defaultTypes as well if they cause cascading
       // errors.
     }
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 3057286..615343c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -179,7 +179,7 @@
         new List<DartType>.filled(typedef.typeParameters.length, null);
     for (int i = 0; i < bounds.length; ++i) {
       bounds[i] = typedef.typeParameters[i].bound;
-      if (bounds[i] == null) {
+      if (identical(bounds[i], TypeParameter.unsetBoundSentinel)) {
         typedef.typeParameters[i].bound = const DynamicType();
       }
     }
@@ -188,7 +188,7 @@
     TypedefType result =
         new TypedefType(typedef, clientLibrary.nonNullable, asTypeArguments);
     for (int i = 0; i < bounds.length; ++i) {
-      if (bounds[i] == null) {
+      if (identical(bounds[i], TypeParameter.unsetBoundSentinel)) {
         // If the bound is not assigned yet, put the corresponding
         // type-parameter type into the list for the nullability re-computation.
         // At this point, [parent] should be a [SourceLibraryBuilder] because
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index a473048..2c32b9c 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -10886,8 +10886,8 @@
         }
         for (int index = 0; index < typeParameters.length; index++) {
           if (!typeParameters[index]
-              .bound!
-              .equals(other.typeParameters[index].bound!, assumptions)) {
+              .bound
+              .equals(other.typeParameters[index].bound, assumptions)) {
             return false;
           }
         }
@@ -11571,7 +11571,7 @@
   }
 
   /// Returns the bound of the type parameter, accounting for promotions.
-  DartType get bound => (promotedBound ?? parameter.bound)!;
+  DartType get bound => promotedBound ?? parameter.bound;
 
   /// Nullability of the type, calculated from its parts.
   ///
@@ -11621,8 +11621,8 @@
     // non-nullable types can be passed in for the type parameter, making the
     // corresponding type parameter types 'undetermined.'  Otherwise, the
     // nullability matches that of the bound.
-    DartType? bound = typeParameter.bound;
-    if (bound == null) {
+    DartType bound = typeParameter.bound;
+    if (identical(bound, TypeParameter.unsetBoundSentinel)) {
       throw new StateError("Can't compute nullability from an absent bound.");
     }
 
@@ -11632,7 +11632,7 @@
     // other ways for such a dependency to exist, they should be checked here.
     bool nullabilityDependsOnItself = false;
     {
-      DartType? type = typeParameter.bound;
+      DartType type = typeParameter.bound;
       while (type is FutureOrType) {
         type = type.typeArgument;
       }
@@ -11971,12 +11971,17 @@
 
   String? name; // Cosmetic name.
 
+  /// Sentinel value used for the [bound] that has not yet been computed. This
+  /// is needed to make the [bound] field non-nullable while supporting
+  /// recursive bounds.
+  static final DartType unsetBoundSentinel = new InvalidType();
+
   /// The bound on the type variable.
   ///
-  /// Should not be null except temporarily during IR construction.  Should
-  /// be set to the root class for type parameters without an explicit bound.
-  // TODO(johnniwinther): Can we make this late non-nullable?
-  DartType? bound;
+  /// This is set to [unsetBoundSentinel] temporarily during IR construction.
+  /// This is set to the `Object?` for type parameters without an explicit
+  /// bound.
+  DartType bound;
 
   /// The default value of the type variable. It is used to provide the
   /// corresponding missing type argument in type annotations and as the
@@ -12002,7 +12007,8 @@
 
   static const int legacyCovariantSerializationMarker = 4;
 
-  TypeParameter([this.name, this.bound, this.defaultType]);
+  TypeParameter([this.name, DartType? bound, this.defaultType])
+      : bound = bound ?? unsetBoundSentinel;
 
   // Must match serialized bit positions.
   static const int FlagGenericCovariantImpl = 1 << 0;
@@ -12039,15 +12045,16 @@
   @override
   void visitChildren(Visitor v) {
     visitList(annotations, v);
-    bound?.accept(v);
+    bound.accept(v);
     defaultType?.accept(v);
   }
 
   @override
   void transformChildren(Transformer v) {
     v.transformList(annotations, this);
+    // ignore: unnecessary_null_comparison
     if (bound != null) {
-      bound = v.visitDartType(bound!);
+      bound = v.visitDartType(bound);
     }
     if (defaultType != null) {
       defaultType = v.visitDartType(defaultType!);
@@ -12057,13 +12064,9 @@
   @override
   void transformOrRemoveChildren(RemovingTransformer v) {
     v.transformExpressionList(annotations, this);
+    // ignore: unnecessary_null_comparison
     if (bound != null) {
-      DartType newBound = v.visitDartType(bound!, dummyDartType);
-      if (identical(newBound, dummyDartType)) {
-        bound = null;
-      } else {
-        bound = newBound;
-      }
+      bound = v.visitDartType(bound, cannotRemoveSentinel);
     }
     if (defaultType != null) {
       DartType newDefaultType = v.visitDartType(defaultType!, dummyDartType);
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 3805110..6e4052a 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -2400,7 +2400,7 @@
       writeByte(node.variance);
     }
     writeStringReference(node.name ?? '');
-    writeNode(node.bound!);
+    writeNode(node.bound);
     // TODO(johnniwinther): Make this non-optional.
     writeOptionalNode(node.defaultType);
   }
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index a399b3a..29a21e3 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -509,7 +509,7 @@
 
   visitTypeParameter(TypeParameter node) {
     TypeParameter newNode = typeParams[node]!;
-    newNode.bound = visitType(node.bound!);
+    newNode.bound = visitType(node.bound);
     if (node.defaultType != null) {
       newNode.defaultType = visitType(node.defaultType!);
     }
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 63ad64c..4123eec 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -1180,7 +1180,7 @@
     // BOTTOM(X extends T) is true iff BOTTOM(T).
     if (type is TypeParameterType && type.isPotentiallyNonNullable) {
       assert(type.promotedBound == null);
-      return isBottom(type.parameter.bound!);
+      return isBottom(type.parameter.bound);
     }
 
     return false;
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 17b0a06..47b03e6 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -87,7 +87,7 @@
 
   void visitFunctionType(FunctionType node) {
     for (TypeParameter typeParameter in node.typeParameters) {
-      typeParameter.bound!.accept(this);
+      typeParameter.bound.accept(this);
       typeParameter.defaultType?.accept(this);
     }
     for (DartType parameter in node.positionalParameters) {
@@ -164,9 +164,9 @@
   List<DartType> bounds =
       new List<DartType>.filled(typeParameters.length, dummyDartType);
   for (int i = 0; i < typeParameters.length; i++) {
-    DartType? bound = typeParameters[i].bound;
+    DartType bound = typeParameters[i].bound;
     bool isContravariant = typeParameters[i].variance == Variance.contravariant;
-    if (bound == null) {
+    if (identical(bound, TypeParameter.unsetBoundSentinel)) {
       bound = isNonNullableByDefault && isContravariant
           ? const NeverType.nonNullable()
           : const DynamicType();
@@ -326,7 +326,7 @@
 
     for (TypeParameter parameter in type.typeParameters) {
       result.addAll(findTypeArgumentIssues(
-          parameter.bound!, typeEnvironment, subtypeCheckMode,
+          parameter.bound, typeEnvironment, subtypeCheckMode,
           allowSuperBounded: true,
           isNonNullableByDefault: isNonNullableByDefault,
           areGenericArgumentsAllowed: areGenericArgumentsAllowed));
@@ -380,7 +380,7 @@
       result.add(new TypeArgumentIssue(i, argument, variables[i], type,
           isGenericTypeAsArgumentIssue: true));
     } else if (variables[i].bound is! InvalidType) {
-      DartType bound = substitute(variables[i].bound!, substitutionMap);
+      DartType bound = substitute(variables[i].bound, substitutionMap);
       if (!isNonNullableByDefault) {
         bound = legacyErasure(bound);
       }
@@ -434,7 +434,7 @@
       // Generic function types aren't allowed as type arguments either.
       isCorrectSuperBounded = false;
     } else if (!typeEnvironment.isSubtypeOf(argument,
-        substitute(variables[i].bound!, substitutionMap), subtypeCheckMode)) {
+        substitute(variables[i].bound, substitutionMap), subtypeCheckMode)) {
       isCorrectSuperBounded = false;
     }
   }
@@ -499,7 +499,7 @@
       result.add(new TypeArgumentIssue(i, argument, parameters[i], null,
           isGenericTypeAsArgumentIssue: true));
     } else if (parameters[i].bound is! InvalidType) {
-      DartType bound = substitute(parameters[i].bound!, substitutionMap);
+      DartType bound = substitute(parameters[i].bound, substitutionMap);
       if (!isNonNullableByDefault) {
         bound = legacyErasure(bound);
       }
@@ -817,7 +817,7 @@
       // variance of [typeParameter] in the entire type invariant.  The
       // invocation of the visitor below is made to simply figure out if
       // [typeParameter] occurs in the bound.
-      if (computeVariance(typeParameter, functionTypeParameter.bound!,
+      if (computeVariance(typeParameter, functionTypeParameter.bound,
               computedVariances: computedVariances) !=
           Variance.unrelated) {
         result = Variance.invariant;
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index b626fa1..d18083c 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -75,7 +75,7 @@
 
       for (int i = 0; i < newTypeParameters.length; i++) {
         DartType? newBound =
-            mergeTypes(a.typeParameters[i].bound!, b.typeParameters[i].bound!);
+            mergeTypes(a.typeParameters[i].bound, b.typeParameters[i].bound);
         if (newBound == null) {
           return null;
         }
diff --git a/pkg/kernel/lib/src/norm.dart b/pkg/kernel/lib/src/norm.dart
index 78ab826..0cc5d54 100644
--- a/pkg/kernel/lib/src/norm.dart
+++ b/pkg/kernel/lib/src/norm.dart
@@ -93,7 +93,7 @@
   @override
   DartType? visitTypeParameterType(TypeParameterType node, int variance) {
     if (node.promotedBound == null) {
-      DartType bound = node.parameter.bound!;
+      DartType bound = node.parameter.bound;
       if (normalizesToNever(bound)) {
         DartType result = NeverType.fromNullability(node.nullability);
         return result.accept1(this, variance) ?? result;
@@ -118,7 +118,7 @@
         assert(!coreTypes.isTop(bound));
         return new TypeParameterType(node.parameter, node.declaredNullability);
       } else if (bound == coreTypes.objectNonNullableRawType &&
-          norm(coreTypes, node.parameter.bound!) ==
+          norm(coreTypes, node.parameter.bound) ==
               coreTypes.objectNonNullableRawType) {
         return new TypeParameterType(node.parameter, node.declaredNullability);
       } else if (identical(bound, node.promotedBound)) {
@@ -143,7 +143,7 @@
       return true;
     } else if (type is TypeParameterType) {
       if (type.promotedBound == null) {
-        return normalizesToNever(type.parameter.bound!);
+        return normalizesToNever(type.parameter.bound);
       } else {
         return normalizesToNever(type.promotedBound!);
       }
diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart
index 5874ca7..cb4b9e6 100644
--- a/pkg/kernel/lib/src/printer.dart
+++ b/pkg/kernel/lib/src/printer.dart
@@ -259,7 +259,7 @@
       for (TypeParameter typeParameter in typeParameters) {
         _sb.write(comma);
         _sb.write(typeParameter.name);
-        DartType bound = typeParameter.bound!;
+        DartType bound = typeParameter.bound;
 
         bool isTopObject(DartType type) {
           if (type is InterfaceType &&
@@ -401,7 +401,7 @@
         }
         _sb.write(node.typeParameters[index].name);
         _sb.write(' extends ');
-        writeType(node.typeParameters[index].bound!);
+        writeType(node.typeParameters[index].bound);
       }
       _sb.write('>');
     }
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index a3db97a2..ced29bc 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -24,7 +24,7 @@
       //   instantiate_to_bound/non_simple_class_parametrized_typedef_cycle
       // fails with this.
       DartType? newBound = typeParameter.bound
-          ?.accept1(this, Variance.combine(variance, Variance.invariant));
+          .accept1(this, Variance.combine(variance, Variance.invariant));
       DartType? newDefaultType = typeParameter.defaultType
           ?.accept1(this, Variance.combine(variance, Variance.invariant));
       if (newBound != null || newDefaultType != null) {
@@ -48,7 +48,7 @@
           Substitution.fromPairs(node.typeParameters, typeParameterTypes);
       for (int i = 0; i < newTypeParameters.length; i++) {
         newTypeParameters[i].bound =
-            substitution.substituteType(newTypeParameters[i].bound!);
+            substitution.substituteType(newTypeParameters[i].bound);
       }
     }
 
diff --git a/pkg/kernel/lib/src/standard_bounds.dart b/pkg/kernel/lib/src/standard_bounds.dart
index 8794dec..81e1974 100644
--- a/pkg/kernel/lib/src/standard_bounds.dart
+++ b/pkg/kernel/lib/src/standard_bounds.dart
@@ -232,7 +232,7 @@
     if (s is TypeParameterType && t is TypeParameterType) {
       assert(s.promotedBound == null);
       assert(t.promotedBound == null);
-      return morebottom(s.parameter.bound!, t.parameter.bound!);
+      return morebottom(s.parameter.bound, t.parameter.bound);
     }
 
     throw new UnsupportedError("morebottom($s, $t)");
@@ -947,8 +947,8 @@
           // TODO(dmitryas): Figure out if a procedure for syntactic equality
           // should be used instead.
           if (!areMutualSubtypes(
-              f.typeParameters[i].bound!,
-              substitution.substituteType(g.typeParameters[i].bound!),
+              f.typeParameters[i].bound,
+              substitution.substituteType(g.typeParameters[i].bound),
               SubtypeCheckMode.withNullabilities)) {
             boundsMatch = false;
           }
@@ -1146,8 +1146,8 @@
           // TODO(dmitryas): Figure out if a procedure for syntactic
           // equality should be used instead.
           if (!areMutualSubtypes(
-              f.typeParameters[i].bound!,
-              substitution.substituteType(g.typeParameters[i].bound!),
+              f.typeParameters[i].bound,
+              substitution.substituteType(g.typeParameters[i].bound),
               SubtypeCheckMode.withNullabilities)) {
             boundsMatch = false;
           }
@@ -1230,12 +1230,12 @@
               topFunctionType: coreTypes.functionNonNullableRawType,
               unhandledTypeHandler: (type, recursor) => false);
       return _getNullabilityAwareStandardUpperBound(
-              eliminator.eliminateToGreatest(type1.parameter.bound!),
+              eliminator.eliminateToGreatest(type1.parameter.bound),
               type2,
               clientLibrary)
           .withDeclaredNullability(uniteNullabilities(
               type1.declaredNullability,
-              uniteNullabilities(type1.parameter.bound!.declaredNullability,
+              uniteNullabilities(type1.parameter.bound.declaredNullability,
                   type2.declaredNullability)));
     } else {
       // UP(X1 & B1, T2) =
@@ -1672,14 +1672,14 @@
       // we need to replicate that behavior?
       return getStandardUpperBound(
           Substitution.fromMap({type1.parameter: coreTypes.objectLegacyRawType})
-              .substituteType(type1.parameter.bound!),
+              .substituteType(type1.parameter.bound),
           type2,
           clientLibrary);
     } else if (type2 is TypeParameterType) {
       return getStandardUpperBound(
           type1,
           Substitution.fromMap({type2.parameter: coreTypes.objectLegacyRawType})
-              .substituteType(type2.parameter.bound!),
+              .substituteType(type2.parameter.bound),
           clientLibrary);
     } else {
       // We should only be called when at least one of the types is a
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index 0c4abbc..550417c 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -357,7 +357,7 @@
   IsSubtypeOf isTypeParameterRelated(
       TypeParameterType s, InterfaceType t, Types types) {
     return types
-        .performNullabilityAwareSubtypeCheck(s.parameter.bound!, t)
+        .performNullabilityAwareSubtypeCheck(s.parameter.bound, t)
         .and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
   }
 
@@ -437,7 +437,7 @@
         TypeParameter sTypeVariable = sTypeVariables[i];
         TypeParameter tTypeVariable = tTypeVariables[i];
         result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
-            sTypeVariable.bound!, tTypeVariable.bound!));
+            sTypeVariable.bound, tTypeVariable.bound));
         typeVariableSubstitution.add(new TypeParameterType.forAlphaRenaming(
             sTypeVariable, tTypeVariable));
       }
@@ -451,8 +451,8 @@
           TypeParameter sTypeVariable = sTypeVariables[i];
           TypeParameter tTypeVariable = tTypeVariables[i];
           result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
-              substitution.substituteType(sTypeVariable.bound!),
-              tTypeVariable.bound!));
+              substitution.substituteType(sTypeVariable.bound),
+              tTypeVariable.bound));
           if (!result.isSubtypeWhenIgnoringNullabilities()) {
             return const IsSubtypeOf.never();
           }
@@ -573,7 +573,7 @@
       TypeParameterType s, FunctionType t, Types types) {
     // Rule 13.
     return types
-        .performNullabilityAwareSubtypeCheck(s.parameter.bound!, t)
+        .performNullabilityAwareSubtypeCheck(s.parameter.bound, t)
         .and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
   }
 
@@ -828,9 +828,9 @@
             s, t.typeArgument.withDeclaredNullability(t.nullability))
         // Rule 13.
         .orSubtypeCheckFor(
-            s.parameter.bound!.withDeclaredNullability(
+            s.parameter.bound.withDeclaredNullability(
                 combineNullabilitiesForSubstitution(
-                    s.parameter.bound!.nullability, s.nullability)),
+                    s.parameter.bound.nullability, s.nullability)),
             t,
             types)
         // Rule 10.
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 691610d..fcc984c 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -322,9 +322,10 @@
       if (arguments.isNotEmpty) {
         throw "Type variable can't have arguments (${node.name})";
       }
-      Nullability nullability = declaration.bound == null
-          ? null
-          : TypeParameterType.computeNullabilityFromBound(declaration);
+      Nullability nullability =
+          identical(declaration.bound, TypeParameter.unsetBoundSentinel)
+              ? null
+              : TypeParameterType.computeNullabilityFromBound(declaration);
       TypeParameterType type = new TypeParameterType(
           declaration,
           interpretParsedNullability(node.parsedNullability,
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 27edbc1..84484e7 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -2515,7 +2515,7 @@
     }
     writeWord(getTypeParameterName(node));
     writeSpaced('extends');
-    writeType(node.bound!);
+    writeType(node.bound);
     if (node.defaultType != null) {
       writeSpaced('=');
       writeType(node.defaultType!);
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 5abc570..82aaee6 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -1196,7 +1196,7 @@
     unzipTypeParameterDefaultType);
 
 TypeParameter zipTypeParameterBound(TypeParameter node, DartType? bound) {
-  return node..bound = bound;
+  return node..bound = bound!;
 }
 
 Tuple2<TypeParameter, DartType?> unzipTypeParameterBound(TypeParameter node) {
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index ebf18f2..d40825c 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -40,7 +40,7 @@
     result[parameter] = const DynamicType();
   }
   for (TypeParameter parameter in host.typeParameters) {
-    result[parameter] = substitute(parameter.bound!, result);
+    result[parameter] = substitute(parameter.bound, result);
   }
   return result;
 }
@@ -120,7 +120,7 @@
     TypeParameter typeParameter = typeParameters[i];
     TypeParameter freshTypeParameter = freshParameters[i];
 
-    freshTypeParameter.bound = substitute(typeParameter.bound!, map);
+    freshTypeParameter.bound = substitute(typeParameter.bound, map);
     freshTypeParameter.defaultType = typeParameter.defaultType != null
         ? substitute(typeParameter.defaultType!, map)
         : null;
@@ -249,7 +249,7 @@
       upper[parameter] = const DynamicType();
     }
     for (TypeParameter parameter in class_.typeParameters) {
-      upper[parameter] = substitute(parameter.bound!, upper);
+      upper[parameter] = substitute(parameter.bound, upper);
     }
     return fromUpperAndLowerBounds(upper, {});
   }
@@ -383,7 +383,7 @@
     TypeParameter fresh = new TypeParameter(node.name);
     TypeParameterType typeParameterType = substitution[node] =
         new TypeParameterType.forAlphaRenaming(node, fresh);
-    fresh.bound = visit(node.bound!);
+    fresh.bound = visit(node.bound);
     if (node.defaultType != null) {
       fresh.defaultType = visit(node.defaultType!);
     }
@@ -700,7 +700,7 @@
 
   bool handleTypeParameter(TypeParameter node) {
     assert(!variables.contains(node));
-    if (node.bound!.accept(this)) return true;
+    if (node.bound.accept(this)) return true;
     if (node.defaultType == null) return false;
     return node.defaultType!.accept(this);
   }
@@ -759,7 +759,7 @@
 
   bool handleTypeParameter(TypeParameter node) {
     assert(variables.contains(node));
-    if (node.bound!.accept(this)) return true;
+    if (node.bound.accept(this)) return true;
     if (node.defaultType == null) return false;
     return node.defaultType!.accept(this);
   }
@@ -818,7 +818,7 @@
 
   bool handleTypeParameter(TypeParameter node) {
     assert(variables.contains(node));
-    if (node.bound!.accept(this)) return true;
+    if (node.bound.accept(this)) return true;
     if (node.defaultType == null) return false;
     return node.defaultType!.accept(this);
   }
@@ -1068,7 +1068,7 @@
     //  - The greatest closure of `S` with respect to `L` is `Function`
     if (node.typeParameters.isNotEmpty) {
       for (TypeParameter typeParameter in node.typeParameters) {
-        if (containsTypeVariable(typeParameter.bound!, eliminationTargets,
+        if (containsTypeVariable(typeParameter.bound, eliminationTargets,
             unhandledTypeHandler: unhandledTypeHandler)) {
           return getFunctionReplacement(variance);
         }
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 9431e8e..01e2f7d 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -182,7 +182,7 @@
   void declareTypeParameters(List<TypeParameter> parameters) {
     for (int i = 0; i < parameters.length; ++i) {
       TypeParameter parameter = parameters[i];
-      if (parameter.bound == null) {
+      if (identical(parameter.bound, TypeParameter.unsetBoundSentinel)) {
         problem(
             currentParent, "Missing bound for type parameter '$parameter'.");
       }
@@ -434,7 +434,7 @@
     }
     declareTypeParameters(node.typeParameters);
     for (TypeParameter typeParameter in node.typeParameters) {
-      typeParameter.bound?.accept(this);
+      typeParameter.bound.accept(this);
       if (typeParameter.annotations.isNotEmpty) {
         problem(
             typeParameter, "Annotation on type parameter in function type.");
diff --git a/tests/language/variable/inst_field_initializer1_test.dart b/tests/language/variable/inst_field_initializer1_test.dart
index edc85c8..550a03e 100644
--- a/tests/language/variable/inst_field_initializer1_test.dart
+++ b/tests/language/variable/inst_field_initializer1_test.dart
@@ -10,8 +10,6 @@
   //         ^
   // [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
   // [cfe] Can't access 'this' in a field initializer to read 'x'.
-  //         ^
-  // [analyzer] STATIC_WARNING.TOP_LEVEL_INSTANCE_GETTER
 }
 
 void main() {
diff --git a/tests/language_2/variable/inst_field_initializer1_test.dart b/tests/language_2/variable/inst_field_initializer1_test.dart
index edc85c8..550a03e 100644
--- a/tests/language_2/variable/inst_field_initializer1_test.dart
+++ b/tests/language_2/variable/inst_field_initializer1_test.dart
@@ -10,8 +10,6 @@
   //         ^
   // [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
   // [cfe] Can't access 'this' in a field initializer to read 'x'.
-  //         ^
-  // [analyzer] STATIC_WARNING.TOP_LEVEL_INSTANCE_GETTER
 }
 
 void main() {
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index 471f72f..948354e 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -28,6 +28,9 @@
 Force build to test recipe changes
 Trigger bots
 Trigger bots
+Trigger builds to check recipe changes
+Trigger builds to check recipe changes
+Trigger builds to check recipe changes
 
 Analyzer branch commits:
 Force build on new analyzer-branch linux build with new workflow
diff --git a/tools/VERSION b/tools/VERSION
index 0c01fa4..91ebc17 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 20
+PRERELEASE 21
 PRERELEASE_PATCH 0
\ No newline at end of file