Version 2.10.0-134.0.dev

Merge commit 'c9576a1dac4b155be545ac396e2a532a1208d7e9' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
index 36658b3..21cdd9c 100644
--- a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
@@ -139,19 +139,10 @@
 
     // If `Q` is a legacy type `Q0*` then the match holds under constraint
     // set `C`:
+    //   Only if `P` is a subtype match for `Q?` under constraint set `C`.
     if (Q_nullability == NullabilitySuffix.star) {
-      if (identical(P, DynamicTypeImpl.instance) ||
-          identical(P, VoidTypeImpl.instance)) {
-        // If `P` is `dynamic` or `void` and `P` is a subtype match
-        // for `Q0` under constraint set `C`.
-        var Q0 = (Q as TypeImpl).withNullability(NullabilitySuffix.none);
-        return trySubtypeMatch(P, Q0, leftSchema);
-      } else {
-        // Or if `P` is not `dynamic` or `void` and `P` is a subtype match
-        // for `Q0?` under constraint set `C`.
-        var Qq = (Q as TypeImpl).withNullability(NullabilitySuffix.question);
-        return trySubtypeMatch(P, Qq, leftSchema);
-      }
+      var Qq = (Q as TypeImpl).withNullability(NullabilitySuffix.question);
+      return trySubtypeMatch(P, Qq, leftSchema);
     }
 
     // If `Q` is `FutureOr<Q0>` the match holds under constraint set `C`:
@@ -210,16 +201,6 @@
         _constraints.length = rewind;
       }
 
-      // Or if `P` is `dynamic` or `void` and `Object` is a subtype match
-      // for `Q0` under constraint set `C`.
-      if (identical(P, DynamicTypeImpl.instance) ||
-          identical(P, VoidTypeImpl.instance)) {
-        if (trySubtypeMatch(_typeSystem.objectNone, Q0, leftSchema)) {
-          return true;
-        }
-        _constraints.length = rewind;
-      }
-
       // Or if `P` is a subtype match for `Q0` under non-empty
       // constraint set `C`.
       var P_matches_Q0 = trySubtypeMatch(P, Q0, leftSchema);
diff --git a/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
index 63715f5..87109c8b 100644
--- a/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_constraint_gatherer_test.dart
@@ -841,29 +841,6 @@
     _checkMatch([T], numStar, T_star, true, ['num <: T <: _']);
   }
 
-  /// If `Q` is a legacy type `Q0*` then the match holds under constraint
-  /// set `C`:
-  ///   If `P` is `dynamic` or `void` and `P` is a subtype match for `Q0`
-  ///   under constraint set `C`.
-  test_left_top_right_legacy() {
-    var U = typeParameter('U', bound: objectNone);
-    var U_star = typeParameterTypeStar(U);
-
-    _checkMatch([U], dynamicNone, U_star, false, ['dynamic <: U <: _']);
-    _checkMatch([U], voidNone, U_star, false, ['void <: U <: _']);
-  }
-
-  /// If `Q` is `Q0?` the match holds under constraint set `C`:
-  ///   Or if `P` is `dynamic` or `void` and `Object` is a subtype match
-  ///   for `Q0` under constraint set `C`.
-  test_left_top_right_nullable() {
-    var U = typeParameter('U', bound: objectNone);
-    var U_question = typeParameterTypeQuestion(U);
-
-    _checkMatch([U], dynamicNone, U_question, false, ['Object <: U <: _']);
-    _checkMatch([U], voidNone, U_question, false, ['Object <: U <: _']);
-  }
-
   /// If `P` is a type variable `X` in `L`, then the match holds:
   ///   Under constraint `_ <: X <: Q`.
   test_left_typeParameter() {
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index 0f36155..80975a0 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -2600,34 +2600,4 @@
 
     assertType(findNode.cascade('A()'), 'A');
   }
-
-  test_typeArgumentTypes_generic_inferred_leftTop_dynamic() async {
-    await assertNoErrorsInCode('''
-void foo<T extends Object>(T? value) {}
-
-void f(dynamic o) {
-  foo(o);
-}
-''');
-
-    assertTypeArgumentTypes(
-      findNode.methodInvocation('foo(o)'),
-      ['Object'],
-    );
-  }
-
-  test_typeArgumentTypes_generic_inferred_leftTop_void() async {
-    await assertNoErrorsInCode('''
-void foo<T extends Object>(List<T?> value) {}
-
-void f(List<void> o) {
-  foo(o);
-}
-''');
-
-    assertTypeArgumentTypes(
-      findNode.methodInvocation('foo(o)'),
-      ['Object'],
-    );
-  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 5b3cbd7..b7a9d24 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -2965,76 +2965,84 @@
       return combinedMemberSignatureResult =
           declarations.first.getMember(hierarchy);
     }
-    bool isNonNullableByDefault = classBuilder.library.isNonNullableByDefault;
-    DartType thisType = hierarchy.coreTypes
-        .thisInterfaceType(classBuilder.cls, classBuilder.library.nonNullable);
-    List<DartType> candidateTypes = new List<DartType>(declarations.length);
     ClassMember bestSoFar;
     int bestSoFarIndex;
-    DartType bestTypeSoFar;
     Map<DartType, int> mutualSubtypes;
-    for (int candidateIndex = declarations.length - 1;
-        candidateIndex >= 0;
-        candidateIndex--) {
-      ClassMember candidate = declarations[candidateIndex];
-      Member target = candidate.getMember(hierarchy);
-      assert(target != null,
-          "No member computed for ${candidate} (${candidate.runtimeType})");
-      DartType candidateType = computeMemberType(hierarchy, thisType, target);
-      if (!isNonNullableByDefault) {
-        candidateType = legacyErasure(hierarchy.coreTypes, candidateType);
-      }
-      candidateTypes[candidateIndex] = candidateType;
-      if (bestSoFar == null) {
-        bestSoFar = candidate;
-        bestTypeSoFar = candidateType;
-        bestSoFarIndex = candidateIndex;
-      } else {
-        if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
-          debug?.log("Combined Member Signature: ${candidate.fullName} "
-              "${candidateType} <: ${bestSoFar.fullName} ${bestTypeSoFar}");
-          if (isNonNullableByDefault &&
-              isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
-            if (mutualSubtypes == null) {
-              mutualSubtypes = {
-                bestTypeSoFar: bestSoFarIndex,
-                candidateType: candidateIndex
-              };
-            } else {
-              mutualSubtypes[candidateType] = candidateIndex;
-            }
-          } else {
-            mutualSubtypes = null;
-          }
-          bestSoFarIndex = candidateIndex;
+    if (declarations.length == 1) {
+      bestSoFar = declarations[0];
+      bestSoFarIndex = 0;
+    } else {
+      DartType thisType = hierarchy.coreTypes.thisInterfaceType(
+          classBuilder.cls, classBuilder.library.nonNullable);
+      bool isNonNullableByDefault = classBuilder.library.isNonNullableByDefault;
+
+      DartType bestTypeSoFar;
+      List<DartType> candidateTypes = new List<DartType>(declarations.length);
+      for (int candidateIndex = declarations.length - 1;
+          candidateIndex >= 0;
+          candidateIndex--) {
+        ClassMember candidate = declarations[candidateIndex];
+        Member target = candidate.getMember(hierarchy);
+        assert(target != null,
+            "No member computed for ${candidate} (${candidate.runtimeType})");
+        DartType candidateType = computeMemberType(hierarchy, thisType, target);
+        if (!isNonNullableByDefault) {
+          candidateType = legacyErasure(hierarchy.coreTypes, candidateType);
+        }
+        candidateTypes[candidateIndex] = candidateType;
+        if (bestSoFar == null) {
           bestSoFar = candidate;
           bestTypeSoFar = candidateType;
+          bestSoFarIndex = candidateIndex;
         } else {
-          debug?.log("Combined Member Signature: "
-              "${candidate.fullName} !<: ${bestSoFar.fullName}");
-        }
-      }
-    }
-    if (bestSoFar != null) {
-      debug?.log("Combined Member Signature bestSoFar: ${bestSoFar.fullName}");
-      for (int candidateIndex = 0;
-          candidateIndex < declarations.length;
-          candidateIndex++) {
-        ClassMember candidate = declarations[candidateIndex];
-        DartType candidateType = candidateTypes[candidateIndex];
-        if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
-          debug?.log("Combined Member Signature: "
-              "${bestSoFar.fullName} !<: ${candidate.fullName}");
-
-          if (!shouldOverrideProblemBeOverlooked(classBuilder)) {
-            bestSoFar = null;
-            bestTypeSoFar = null;
-            mutualSubtypes = null;
+          if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
+            debug?.log("Combined Member Signature: ${candidate.fullName} "
+                "${candidateType} <: ${bestSoFar.fullName} ${bestTypeSoFar}");
+            if (isNonNullableByDefault &&
+                isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
+              if (mutualSubtypes == null) {
+                mutualSubtypes = {
+                  bestTypeSoFar: bestSoFarIndex,
+                  candidateType: candidateIndex
+                };
+              } else {
+                mutualSubtypes[candidateType] = candidateIndex;
+              }
+            } else {
+              mutualSubtypes = null;
+            }
+            bestSoFarIndex = candidateIndex;
+            bestSoFar = candidate;
+            bestTypeSoFar = candidateType;
+          } else {
+            debug?.log("Combined Member Signature: "
+                "${candidate.fullName} !<: ${bestSoFar.fullName}");
           }
-          break;
+        }
+      }
+      if (bestSoFar != null) {
+        debug?.log("Combined Member Signature bestSoFar: "
+            "${bestSoFar.fullName}");
+        for (int candidateIndex = 0;
+            candidateIndex < declarations.length;
+            candidateIndex++) {
+          ClassMember candidate = declarations[candidateIndex];
+          DartType candidateType = candidateTypes[candidateIndex];
+          if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
+            debug?.log("Combined Member Signature: "
+                "${bestSoFar.fullName} !<: ${candidate.fullName}");
+
+            if (!shouldOverrideProblemBeOverlooked(classBuilder)) {
+              bestSoFar = null;
+              bestTypeSoFar = null;
+              mutualSubtypes = null;
+            }
+            break;
+          }
         }
       }
     }
+
     if (bestSoFar == null) {
       String name = classBuilder.fullNameForErrors;
       int length = classBuilder.isAnonymousMixinApplication ? 1 : name.length;
@@ -3058,16 +3066,16 @@
     debug?.log("Combined Member Signature of ${fullNameForErrors}: "
         "${bestSoFar.fullName}");
 
-    ProcedureKind kind = ProcedureKind.Method;
-    Member bestMemberSoFar = bestSoFar.getMember(hierarchy);
-    if (bestSoFar.isProperty) {
-      kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
-    } else if (bestMemberSoFar is Procedure &&
-        bestMemberSoFar.kind == ProcedureKind.Operator) {
-      kind = ProcedureKind.Operator;
-    }
-
     if (modifyKernel) {
+      ProcedureKind kind = ProcedureKind.Method;
+      Member bestMemberSoFar = bestSoFar.getMember(hierarchy);
+      if (bestSoFar.isProperty) {
+        kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+      } else if (bestMemberSoFar is Procedure &&
+          bestMemberSoFar.kind == ProcedureKind.Operator) {
+        kind = ProcedureKind.Operator;
+      }
+
       debug?.log("Combined Member Signature of ${fullNameForErrors}: new "
           "ForwardingNode($classBuilder, $bestSoFar, $declarations, $kind)");
       Member stub = new ForwardingNode(
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
index 5fa02e2..0ed93a7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -11,9 +11,12 @@
         Expression,
         Field,
         FunctionNode,
+        FunctionType,
         Member,
         Name,
         NamedExpression,
+        NamedType,
+        Nullability,
         Procedure,
         ProcedureKind,
         ReturnStatement,
@@ -83,6 +86,203 @@
   /// forwarding stubs if necessary.
   Member finalize() => _computeCovarianceFixes();
 
+  /// Creates a getter member signature for [interfaceMember] with the given
+  /// [type].
+  Member _createGetterMemberSignature(Member interfaceMember, DartType type) {
+    Procedure referenceFrom;
+    if (classBuilder.referencesFromIndexed != null) {
+      referenceFrom = classBuilder.referencesFromIndexed
+          .lookupProcedureNotSetter(name.name);
+    }
+    return new Procedure(name, kind, new FunctionNode(null, returnType: type),
+        isAbstract: true,
+        isMemberSignature: true,
+        fileUri: enclosingClass.fileUri,
+        memberSignatureOrigin: interfaceMember,
+        reference: referenceFrom?.reference)
+      ..startFileOffset = enclosingClass.fileOffset
+      ..fileOffset = enclosingClass.fileOffset
+      ..parent = enclosingClass;
+  }
+
+  /// Creates a setter member signature for [interfaceMember] with the given
+  /// [type]. The flags of parameter is set according to [isCovariant] and
+  /// [isGenericCovariantImpl] and the [parameterName] is used, if provided.
+  Member _createSetterMemberSignature(Member interfaceMember, DartType type,
+      {bool isCovariant, bool isGenericCovariantImpl, String parameterName}) {
+    assert(isCovariant != null);
+    assert(isGenericCovariantImpl != null);
+    Procedure referenceFrom;
+    if (classBuilder.referencesFromIndexed != null) {
+      referenceFrom =
+          classBuilder.referencesFromIndexed.lookupProcedureSetter(name.name);
+    }
+    return new Procedure(
+        name,
+        kind,
+        new FunctionNode(null,
+            returnType: const VoidType(),
+            positionalParameters: [
+              new VariableDeclaration(parameterName ?? '_',
+                  type: type, isCovariant: isCovariant)
+                ..isGenericCovariantImpl = isGenericCovariantImpl
+            ]),
+        isAbstract: true,
+        isMemberSignature: true,
+        fileUri: enclosingClass.fileUri,
+        memberSignatureOrigin: interfaceMember,
+        reference: referenceFrom?.reference)
+      ..startFileOffset = enclosingClass.fileOffset
+      ..fileOffset = enclosingClass.fileOffset
+      ..parent = enclosingClass;
+  }
+
+  /// Creates a legacy member signature for the field [interfaceMember] if the
+  /// type of [interfaceMember] contains non-legacy nullabilities.
+  Member _createLegacyMemberSignatureForField(Field interfaceMember) {
+    DartType type = interfaceMember.type;
+    if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+      Substitution substitution =
+          _substitutionFor(null, interfaceMember, enclosingClass);
+      type = substitution.substituteType(type);
+    }
+    DartType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+    if (legacyType == null) {
+      return interfaceMember;
+    } else {
+      // We base the decision to add a member signature on whether the legacy
+      // erasure of the declared type is different from the declared type, i.e.
+      // whether the declared type contained non-legacy nullabilities.
+      //
+      // This is slightly different from checking whether the legacy erasure of
+      // the inherited type is different from the
+      if (kind == ProcedureKind.Getter) {
+        return _createGetterMemberSignature(interfaceMember, legacyType);
+      } else {
+        assert(kind == ProcedureKind.Setter);
+        return _createSetterMemberSignature(interfaceMember, legacyType,
+            isCovariant: interfaceMember.isCovariant,
+            isGenericCovariantImpl: interfaceMember.isGenericCovariantImpl);
+      }
+    }
+  }
+
+  /// Creates a legacy member signature for procedure [interfaceMember] if the
+  /// type of [interfaceMember] contains non-legacy nullabilities.
+  Member _createLegacyMemberSignatureForProcedure(Procedure interfaceMember) {
+    if (interfaceMember.kind == ProcedureKind.Getter) {
+      DartType type = interfaceMember.getterType;
+      if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+        Substitution substitution =
+            _substitutionFor(null, interfaceMember, enclosingClass);
+        type = substitution.substituteType(type);
+      }
+      DartType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+      if (legacyType == null) {
+        return interfaceMember;
+      } else {
+        return _createGetterMemberSignature(interfaceMember, legacyType);
+      }
+    } else if (interfaceMember.kind == ProcedureKind.Setter) {
+      DartType type = interfaceMember.setterType;
+      if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+        Substitution substitution =
+            _substitutionFor(null, interfaceMember, enclosingClass);
+        type = substitution.substituteType(type);
+      }
+      DartType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+      if (legacyType == null) {
+        return interfaceMember;
+      } else {
+        VariableDeclaration parameter =
+            interfaceMember.function.positionalParameters.first;
+        return _createSetterMemberSignature(interfaceMember, legacyType,
+            isCovariant: parameter.isCovariant,
+            isGenericCovariantImpl: parameter.isGenericCovariantImpl,
+            parameterName: parameter.name);
+      }
+    } else {
+      FunctionNode function = interfaceMember.function;
+      FunctionType type = function.computeFunctionType(Nullability.legacy);
+      if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
+        Substitution substitution =
+            _substitutionFor(null, interfaceMember, enclosingClass);
+        type = substitution.substituteType(type);
+      }
+      FunctionType legacyType = rawLegacyErasure(hierarchy.coreTypes, type);
+      if (legacyType == null) {
+        return interfaceMember;
+      }
+      Procedure referenceFrom;
+      if (classBuilder.referencesFromIndexed != null) {
+        referenceFrom = classBuilder.referencesFromIndexed
+            .lookupProcedureNotSetter(name.name);
+      }
+      List<VariableDeclaration> positionalParameters = [];
+      for (int i = 0; i < function.positionalParameters.length; i++) {
+        VariableDeclaration parameter = function.positionalParameters[i];
+        DartType parameterType = legacyType.positionalParameters[i];
+        if (i == 0 && interfaceMember == hierarchy.coreTypes.objectEquals) {
+          // In legacy code we special case `Object.==` to infer `dynamic`
+          // instead `Object!`.
+          parameterType = const DynamicType();
+        }
+        positionalParameters.add(new VariableDeclaration(parameter.name,
+            type: parameterType, isCovariant: parameter.isCovariant)
+          ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+      }
+      List<VariableDeclaration> namedParameters = [];
+      int namedParameterCount = function.namedParameters.length;
+      if (namedParameterCount == 1) {
+        NamedType namedType = legacyType.namedParameters.first;
+        VariableDeclaration parameter = function.namedParameters.first;
+        namedParameters.add(new VariableDeclaration(parameter.name,
+            type: namedType.type, isCovariant: parameter.isCovariant)
+          ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+      } else if (namedParameterCount > 1) {
+        Map<String, DartType> namedTypes = {};
+        for (NamedType namedType in legacyType.namedParameters) {
+          namedTypes[namedType.name] = namedType.type;
+        }
+        for (int i = 0; i < namedParameterCount; i++) {
+          VariableDeclaration parameter = function.namedParameters[i];
+          DartType parameterType = namedTypes[parameter.name];
+          namedParameters.add(new VariableDeclaration(parameter.name,
+              type: parameterType, isCovariant: parameter.isCovariant)
+            ..isGenericCovariantImpl = parameter.isGenericCovariantImpl);
+        }
+      }
+      return new Procedure(
+          name,
+          kind,
+          new FunctionNode(null,
+              typeParameters: legacyType.typeParameters,
+              returnType: legacyType.returnType,
+              positionalParameters: positionalParameters,
+              namedParameters: namedParameters,
+              requiredParameterCount: function.requiredParameterCount),
+          isAbstract: true,
+          isMemberSignature: true,
+          fileUri: enclosingClass.fileUri,
+          memberSignatureOrigin: interfaceMember,
+          reference: referenceFrom?.reference)
+        ..startFileOffset = enclosingClass.fileOffset
+        ..fileOffset = enclosingClass.fileOffset
+        ..parent = enclosingClass;
+    }
+  }
+
+  /// Creates a legacy member signature for [interfaceMember] if the type of
+  /// [interfaceMember] contains non-legacy nullabilities.
+  Member _createLegacyMemberSignature(Member interfaceMember) {
+    if (interfaceMember is Field) {
+      return _createLegacyMemberSignatureForField(interfaceMember);
+    } else {
+      assert(interfaceMember is Procedure);
+      return _createLegacyMemberSignatureForProcedure(interfaceMember);
+    }
+  }
+
   /// Tag the parameters of [interfaceMember] that need type checks
   ///
   /// Parameters can need type checks for calls coming from statically typed
@@ -95,6 +295,18 @@
   /// stub is introduced as a place to put the checks.
   Member _computeCovarianceFixes() {
     Member interfaceMember = combinedMemberSignatureResult.getMember(hierarchy);
+    if (_candidates.length == 1) {
+      // Covariance can only come from [interfaceMember] so we never need a
+      // forwarding stub.
+      if (interfaceMember.isNonNullableByDefault &&
+          !classBuilder.library.isNonNullableByDefault) {
+        // Create a member signature with the legacy erasure type.
+        return _createLegacyMemberSignature(interfaceMember);
+      } else {
+        // Nothing to do.
+        return interfaceMember;
+      }
+    }
 
     List<TypeParameter> interfaceMemberTypeParameters =
         interfaceMember.function?.typeParameters ?? [];
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index a35454f..0ca4f6d 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1016,6 +1016,7 @@
 equivalence
 equivalent
 equivalents
+erasure
 erroneous
 error
 errors
@@ -1809,6 +1810,7 @@
 meant
 measurably
 measure
+measurements
 mechanism
 medium
 meet
diff --git a/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart
new file mode 100644
index 0000000..a167112
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.8
+
+import 'covariant_from_opt_in_lib.dart';
+
+class SubClass extends Class with Mixin {
+  void covariant(SubClass cls) {} // ok
+  void invariant(SubClass cls) {} // error
+  void contravariant(Object cls) {} // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..4a8f587
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+// @dart = 2.8
+import 'covariant_from_opt_in_lib.dart';
+
+class SubClass extends Class with Mixin {
+  void covariant(SubClass cls) {}
+  void invariant(SubClass cls) {}
+  void contravariant(Object cls) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0c09e22
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+// @dart = 2.8
+import 'covariant_from_opt_in_lib.dart';
+
+class SubClass extends Class with Mixin {
+  void contravariant(Object cls) {}
+  void covariant(SubClass cls) {}
+  void invariant(SubClass cls) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.weak.expect
new file mode 100644
index 0000000..2571ea6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart.weak.expect
@@ -0,0 +1,62 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart:11:27: Error: The parameter 'cls' of the method 'SubClass.invariant' has type 'SubClass', which does not match the corresponding type, 'Class', in the overridden method, 'Class with Mixin.invariant'.
+//  - 'SubClass' is from 'pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart'.
+//  - 'Class' is from 'pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in_lib.dart'.
+// Change to a supertype of 'Class', or, for a covariant parameter, a subtype.
+//   void invariant(SubClass cls) {} // error
+//                           ^
+// pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in.dart:9:7: Context: This is the overridden method ('invariant').
+// class SubClass extends Class with Mixin {
+//       ^
+//
+import self as self;
+import "covariant_from_opt_in_lib.dart" as cov;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///covariant_from_opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = cov::Class with cov::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_SubClass&Class&Mixin*
+    : super cov::Class::•()
+    ;
+  abstract member-signature method covariant(covariant cov::Class* cls) → void; -> cov::Class::covariant
+  abstract member-signature method invariant(cov::Class* cls) → void; -> cov::Class::invariant
+  abstract member-signature method contravariant(cov::Class* cls) → void; -> cov::Class::contravariant
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class SubClass extends self::_SubClass&Class&Mixin {
+  synthetic constructor •() → self::SubClass*
+    : super self::_SubClass&Class&Mixin::•()
+    ;
+  method covariant(covariant self::SubClass* cls) → void {}
+  method invariant(self::SubClass* cls) → void {}
+  method contravariant(core::Object* cls) → void {}
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as cov;
+import "dart:core" as core;
+
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+abstract class Class extends core::Object {
+  synthetic constructor •() → cov::Class
+    : super core::Object::•()
+    ;
+  abstract method covariant(covariant cov::Class cls) → void;
+  abstract method invariant(cov::Class cls) → void;
+  abstract method contravariant(cov::Class cls) → void;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in_lib.dart b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in_lib.dart
new file mode 100644
index 0000000..a10e376
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/covariant_from_opt_in_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+mixin Mixin {}
+
+abstract class Class {
+  void covariant(covariant Class cls);
+  void invariant(Class cls);
+  void contravariant(Class cls);
+}
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index d9272d6..fee0310 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -67,6 +67,7 @@
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
 nnbd_mixed/bad_mixins: TypeCheckError
+nnbd_mixed/covariant_from_opt_in: TypeCheckError
 nnbd_mixed/inheritance_from_opt_in: TypeCheckError
 nnbd_mixed/issue41567: TypeCheckError
 nnbd_mixed/messages_with_types_opt_in: TypeCheckError
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 481479e..98fb84a 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1235,8 +1235,10 @@
     leaveScope(memberScope: true);
 
     _currentlyInNonimplementation = currentlyInNonimplementationSaved;
-    assert((node.forwardingStubSuperTarget != null) ||
-        !(node.isForwardingStub && node.function.body != null));
+    assert(
+        (node.forwardingStubSuperTarget != null) ||
+            !(node.isForwardingStub && node.function.body != null),
+        "Invalid forwarding stub $node.");
   }
 
   @override
diff --git a/tests/language/inference/dynamic_nullable_test.dart b/tests/language/inference/dynamic_nullable_test.dart
index 46b6591..6bcb121 100644
--- a/tests/language/inference/dynamic_nullable_test.dart
+++ b/tests/language/inference/dynamic_nullable_test.dart
@@ -55,7 +55,7 @@
 
     var c = C.list(o);
     var f = bar(o);
-    var l = o.whereNotNull();
+    var l = o.whereNotNull;
 
     c.expectStaticType<Exactly<C<Object>>>();
     Expect.type<C<Object>>(c); // Run-time type is subtype of C<Object>.
diff --git a/tools/VERSION b/tools/VERSION
index 941fd96..66e08aa 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 133
+PRERELEASE 134
 PRERELEASE_PATCH 0
\ No newline at end of file