Version 2.15.0-215.0.dev

Merge commit '36caf54631a5c6ced8425ab332577a00dc5de076' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed74bf7..b868d35 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -400,12 +400,25 @@
   `dart pub get/upgrade/downgrade/add/remove` that will result in the `example/`
   folder dependencies to be updated after operating in the current directory.
 
+## 2.14.4 - 2021-10-14
+
+This is a patch release that fixes:
+
+- a memory leak of analyzer plugins (issue [flutter/flutter#90868][]).
+- the Dart VM sometimes loading expired certificates on Windows (issues
+  [#46370][] and [#47420][]).
+
+[flutter/flutter#90868]: https://github.com/flutter/flutter/issues/90868
+[#46370]: https://github.com/dart-lang/sdk/issues/46370
+[#47420]: https://github.com/dart-lang/sdk/issues/47420
+
 ## 2.14.3 - 2021-09-30
 
 This is a patch release that fixes:
 
-- a code completion performance regression [flutter/flutter-intellij#5761][].
-- debug information emitted by the Dart VM [#47289][].
+- a code completion performance regression (issue
+  [flutter/flutter-intellij#5761][]).
+- debug information emitted by the Dart VM (issue [#47289][]).
 
 [flutter/flutter-intellij#5761]:
   https://github.com/flutter/flutter-intellij/issues/5761
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 6d7d02a..b122154 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -1134,12 +1134,12 @@
     } else {
       ir.Class declaringClass = node.interfaceTarget.enclosingClass;
       if (declaringClass.typeParameters.isEmpty) {
-        resultType = node.interfaceTarget.getterType;
+        resultType = node.interfaceTarget.superGetterType;
       } else {
         ir.DartType receiver = typeEnvironment.getTypeAsInstanceOf(thisType,
             declaringClass, currentLibrary, typeEnvironment.coreTypes);
         resultType = ir.Substitution.fromInterfaceType(receiver)
-            .substituteType(node.interfaceTarget.getterType);
+            .substituteType(node.interfaceTarget.superGetterType);
       }
     }
     _staticTypeCache._expressionTypes[node] = resultType;
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index ca5860b..9dc9bd9 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -2006,7 +2006,7 @@
                   superMember.function.positionalParameters[0])) {
         return const [];
       }
-      var setterType = substituteType(superMember.setterType);
+      var setterType = substituteType(superMember.superSetterType);
       if (_types.isTop(setterType)) return const [];
       return [
         js_ast.Method(
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index 414c8c2..abff877 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -701,8 +701,9 @@
       } else if (member.isSetter) {
         type = member.setterType;
       } else {
-        type = member.function
-            .computeFunctionType(classBuilder.cls.enclosingLibrary.nonNullable);
+        // TODO(johnniwinther): Why do we need the specific nullability here?
+        type = member.getterType.withDeclaredNullability(
+            classBuilder.cls.enclosingLibrary.nonNullable);
       }
     } else if (member is Field) {
       type = member.type;
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 2ae41d0..f05f378 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -167,6 +167,10 @@
       superTarget = superTarget.memberSignatureOrigin ?? superTarget;
     }
     procedure.isAbstract = false;
+    FunctionType signatureType = procedure.function
+        .computeFunctionType(procedure.enclosingLibrary.nonNullable);
+    bool isForwardingSemiStub = isForwardingStub && !procedure.isSynthetic;
+    bool needsSignatureType = false;
     Expression superCall;
     // ignore: unnecessary_null_comparison
     assert(superTarget != null,
@@ -197,15 +201,22 @@
           Expression expression = new VariableGet(parameter)
             ..fileOffset = fileOffset;
           DartType superParameterType = type.positionalParameters[index];
-          if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
-              parameter.type,
-              superParameterType,
-              _combinedMemberSignature
-                      .classBuilder.library.isNonNullableByDefault
-                  ? SubtypeCheckMode.withNullabilities
-                  : SubtypeCheckMode.ignoringNullabilities)) {
-            expression = new AsExpression(expression, superParameterType)
-              ..fileOffset = fileOffset;
+          if (isForwardingSemiStub) {
+            if (parameter.type != superParameterType) {
+              parameter.type = superParameterType;
+              needsSignatureType = true;
+            }
+          } else {
+            if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
+                parameter.type,
+                superParameterType,
+                _combinedMemberSignature
+                        .classBuilder.library.isNonNullableByDefault
+                    ? SubtypeCheckMode.withNullabilities
+                    : SubtypeCheckMode.ignoringNullabilities)) {
+              expression = new AsExpression(expression, superParameterType)
+                ..fileOffset = fileOffset;
+            }
           }
           return expression;
         }, growable: true);
@@ -219,15 +230,22 @@
               .singleWhere(
                   (NamedType namedType) => namedType.name == parameter.name)
               .type;
-          if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
-              parameter.type,
-              superParameterType,
-              _combinedMemberSignature
-                      .classBuilder.library.isNonNullableByDefault
-                  ? SubtypeCheckMode.withNullabilities
-                  : SubtypeCheckMode.ignoringNullabilities)) {
-            expression = new AsExpression(expression, superParameterType)
-              ..fileOffset = fileOffset;
+          if (isForwardingSemiStub) {
+            if (parameter.type != superParameterType) {
+              parameter.type = superParameterType;
+              needsSignatureType = true;
+            }
+          } else {
+            if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
+                parameter.type,
+                superParameterType,
+                _combinedMemberSignature
+                        .classBuilder.library.isNonNullableByDefault
+                    ? SubtypeCheckMode.withNullabilities
+                    : SubtypeCheckMode.ignoringNullabilities)) {
+              expression = new AsExpression(expression, superParameterType)
+                ..fileOffset = fileOffset;
+            }
           }
           return new NamedExpression(parameter.name!, expression);
         }, growable: true);
@@ -251,14 +269,22 @@
         int fileOffset = parameter.fileOffset;
         Expression expression = new VariableGet(parameter)
           ..fileOffset = fileOffset;
-        if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
-            parameter.type,
-            superParameterType,
-            _combinedMemberSignature.classBuilder.library.isNonNullableByDefault
-                ? SubtypeCheckMode.withNullabilities
-                : SubtypeCheckMode.ignoringNullabilities)) {
-          expression = new AsExpression(expression, superParameterType)
-            ..fileOffset = fileOffset;
+        if (isForwardingSemiStub) {
+          if (parameter.type != superParameterType) {
+            parameter.type = superParameterType;
+            needsSignatureType = true;
+          }
+        } else {
+          if (!_combinedMemberSignature.hierarchy.types.isSubtypeOf(
+              parameter.type,
+              superParameterType,
+              _combinedMemberSignature
+                      .classBuilder.library.isNonNullableByDefault
+                  ? SubtypeCheckMode.withNullabilities
+                  : SubtypeCheckMode.ignoringNullabilities)) {
+            expression = new AsExpression(expression, superParameterType)
+              ..fileOffset = fileOffset;
+          }
         }
         superCall = new SuperPropertySet(name, expression, superTarget);
         break;
@@ -273,5 +299,8 @@
         ? ProcedureStubKind.ConcreteForwardingStub
         : ProcedureStubKind.ConcreteMixinStub;
     procedure.stubTarget = superTarget;
+    if (needsSignatureType) {
+      procedure.signatureType = signatureType;
+    }
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 426a2e0..91fa5d8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -1504,7 +1504,9 @@
         declaredMember.kind == ProcedureKind.Operator);
     bool seenCovariant = false;
     FunctionNode declaredFunction = declaredMember.function;
+    FunctionType? declaredSignatureType = declaredMember.signatureType;
     FunctionNode interfaceFunction = interfaceMember.function;
+    FunctionType? interfaceSignatureType = interfaceMember.signatureType;
 
     Substitution? interfaceSubstitution = _computeInterfaceSubstitution(
         types,
@@ -1578,9 +1580,17 @@
           declaredFunction.positionalParameters[i];
       VariableDeclaration interfaceParameter =
           interfaceFunction.positionalParameters[i];
+      DartType declaredParameterType = declaredParameter.type;
+      if (declaredSignatureType != null) {
+        declaredParameterType = declaredSignatureType.positionalParameters[i];
+      }
+      DartType interfaceParameterType = interfaceParameter.type;
+      if (interfaceSignatureType != null) {
+        interfaceParameterType = interfaceSignatureType.positionalParameters[i];
+      }
       if (i == 0 &&
           declaredMember.name == equalsName &&
-          declaredParameter.type ==
+          declaredParameterType ==
               types.hierarchy.coreTypes.objectNonNullableRawType &&
           interfaceParameter.type is DynamicType) {
         // TODO(johnniwinther): Add check for opt-in overrides of operator ==.
@@ -1596,8 +1606,8 @@
           declaredMember,
           interfaceMember,
           interfaceMemberOrigin,
-          declaredParameter.type,
-          interfaceParameter.type,
+          declaredParameterType,
+          interfaceParameterType,
           declaredParameter.isCovariantByDeclaration ||
               interfaceParameter.isCovariantByDeclaration,
           declaredParameter,
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 6beac94..e6c4cf0 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -904,6 +904,7 @@
 suite
 summarization
 summarized
+sup
 supermixin
 supplement
 suspension
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart
new file mode 100644
index 0000000..bd46eb8
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'test_lib.dart';
+
+main() {
+  test();
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.strong.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.strong.expect
new file mode 100644
index 0000000..b59abe4
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.strong.expect
@@ -0,0 +1,121 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart: Error: A library can't opt out of null safety by default, when using sound null safety.
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+//   int j = sub.mixinMethod(null);
+//                           ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   int j = sub.mixinMethod(null);
+//               ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   sub.mixinField2 = sub.mixinField1;
+//                         ^
+//
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+import "opt_in_lib.dart" as opt2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  int j = sub.mixinMethod(null);
+              ^" in sub.{opt2::Mixin::mixinMethod}(invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+  int j = sub.mixinMethod(null);
+                          ^" in null as{TypeError,ForNonNullableByDefault} core::int){(core::int) → core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt2::Mixin::mixinField2} = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  sub.mixinField2 = sub.mixinField1;
+                        ^" in sub.{opt2::Mixin::mixinField1}{core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart:5:1: Error: A library can't opt out of null safety by default, when using sound null safety.
+// // @dart=2.9
+// ^^^^^^^^^^^^
+//
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.strong.transformed.expect
new file mode 100644
index 0000000..b59abe4
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.strong.transformed.expect
@@ -0,0 +1,121 @@
+//
+// Problems in component:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart: Error: A library can't opt out of null safety by default, when using sound null safety.
+//
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+//   int j = sub.mixinMethod(null);
+//                           ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   int j = sub.mixinMethod(null);
+//               ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   sub.mixinField2 = sub.mixinField1;
+//                         ^
+//
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+import "opt_in_lib.dart" as opt2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  int j = sub.mixinMethod(null);
+              ^" in sub.{opt2::Mixin::mixinMethod}(invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+  int j = sub.mixinMethod(null);
+                          ^" in null as{TypeError,ForNonNullableByDefault} core::int){(core::int) → core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt2::Mixin::mixinField2} = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  sub.mixinField2 = sub.mixinField1;
+                        ^" in sub.{opt2::Mixin::mixinField1}{core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart:5:1: Error: A library can't opt out of null safety by default, when using sound null safety.
+// // @dart=2.9
+// ^^^^^^^^^^^^
+//
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.textual_outline.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.expect
new file mode 100644
index 0000000..768396e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.expect
@@ -0,0 +1,109 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+//   int j = sub.mixinMethod(null);
+//                           ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   int j = sub.mixinMethod(null);
+//               ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   sub.mixinField2 = sub.mixinField1;
+//                         ^
+//
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+import "opt_in_lib.dart" as opt2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  int j = sub.mixinMethod(null);
+              ^" in sub.{opt2::Mixin::mixinMethod}(invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+  int j = sub.mixinMethod(null);
+                          ^" in null as{TypeError,ForNonNullableByDefault} core::int){(core::int) → core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt2::Mixin::mixinField2} = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  sub.mixinField2 = sub.mixinField1;
+                        ^" in sub.{opt2::Mixin::mixinField1}{core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.outline.expect
new file mode 100644
index 0000000..86e5bd6
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.outline.expect
@@ -0,0 +1,75 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self3;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1;
+  field core::int classField2;
+  synthetic constructor •() → self3::Class
+    ;
+  method classMethod(core::int i) → core::int?
+    ;
+  static method _#new#tearOff() → self3::Class
+    return new self3::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1;
+  field core::int mixinField2;
+  method mixinMethod(core::int i) → core::int?
+    ;
+}
+
+library;
+import self as self4;
+import "opt_in_lib.dart" as self3;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = self3::Class with self3::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self4::_SubClass&Class&Mixin*
+    : super self3::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{self3::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{self3::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{self3::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{self3::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> self3::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> self3::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> self3::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> self3::Class::classField2
+  mixin-super-stub method mixinMethod(core::int* i) → core::int*
+    return super.{self3::Mixin::mixinMethod}(i);
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> self3::Class::classMethod
+  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 self4::_SubClass&Class&Mixin {
+  synthetic constructor •() → self4::SubClass*
+    ;
+  static method _#new#tearOff() → self4::SubClass*
+    return new self4::SubClass::•();
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..768396e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.dart.weak.transformed.expect
@@ -0,0 +1,109 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+//   int j = sub.mixinMethod(null);
+//                           ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   int j = sub.mixinMethod(null);
+//               ^
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   sub.mixinField2 = sub.mixinField1;
+//                         ^
+//
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+import "opt_in_lib.dart" as opt2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  int j = sub.mixinMethod(null);
+              ^" in sub.{opt2::Mixin::mixinMethod}(invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+  int j = sub.mixinMethod(null);
+                          ^" in null as{TypeError,ForNonNullableByDefault} core::int){(core::int) → core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt2::Mixin::mixinField2} = invalid-expression "pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  sub.mixinField2 = sub.mixinField1;
+                        ^" in sub.{opt2::Mixin::mixinField1}{core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart
new file mode 100644
index 0000000..bd46eb8
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'test_lib.dart';
+
+main() {
+  test();
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.strong.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.strong.expect
new file mode 100644
index 0000000..6c83f5a
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.strong.expect
@@ -0,0 +1,93 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = sub.{opt::_SubClass&Class&Mixin::mixinMethod}(null){(core::int*) →* core::int*};
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int*};
+}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart:5:1: Error: A library can't opt out of null safety by default, when using sound null safety.
+// // @dart=2.9
+// ^^^^^^^^^^^^
+//
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  mixin-super-stub method mixinMethod(core::int* i) → core::int*
+    return super.{opt2::Mixin::mixinMethod}(i);
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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 opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.strong.transformed.expect
new file mode 100644
index 0000000..2c29078
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.strong.transformed.expect
@@ -0,0 +1,94 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = sub.{opt::_SubClass&Class&Mixin::mixinMethod}(null){(core::int*) →* core::int*};
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int*};
+}
+
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart:5:1: Error: A library can't opt out of null safety by default, when using sound null safety.
+// // @dart=2.9
+// ^^^^^^^^^^^^
+//
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.textual_outline.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.expect
new file mode 100644
index 0000000..4f8699d
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = sub.{opt::_SubClass&Class&Mixin::mixinMethod}(null){(core::int*) →* core::int*};
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int*};
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  mixin-super-stub method mixinMethod(core::int* i) → core::int*
+    return super.{opt2::Mixin::mixinMethod}(i);
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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 opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.outline.expect
new file mode 100644
index 0000000..2f9c18a
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.outline.expect
@@ -0,0 +1,75 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic
+  ;
+
+library;
+import self as self3;
+import "opt_in_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt::Class with opt::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self3::_SubClass&Class&Mixin*
+    : super opt::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt::Class::classField2
+  mixin-super-stub method mixinMethod(core::int* i) → core::int*
+    return super.{opt::Mixin::mixinMethod}(i);
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt::Class::classMethod
+  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 self3::_SubClass&Class&Mixin {
+  synthetic constructor •() → self3::SubClass*
+    ;
+  static method _#new#tearOff() → self3::SubClass*
+    return new self3::SubClass::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1;
+  field core::int classField2;
+  synthetic constructor •() → opt::Class
+    ;
+  method classMethod(core::int i) → core::int?
+    ;
+  static method _#new#tearOff() → opt::Class
+    return new opt::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1;
+  field core::int mixinField2;
+  method mixinMethod(core::int i) → core::int?
+    ;
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.transformed.expect
new file mode 100644
index 0000000..60ca4c9
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/main.no_link.dart.weak.transformed.expect
@@ -0,0 +1,87 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = sub.{opt::_SubClass&Class&Mixin::mixinMethod}(null){(core::int*) →* core::int*};
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int*};
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+  static method _#new#tearOff() → opt::SubClass*
+    return new opt::SubClass::•();
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+  static method _#new#tearOff() → opt2::Class
+    return new opt2::Class::•();
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {
+    super.{core::Object::toString}();
+  }
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_in_lib.dart b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_in_lib.dart
new file mode 100644
index 0000000..30ed0aa
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_in_lib.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {
+  int? classField1;
+  int classField2 = 0;
+  int? classMethod(int i) {}
+}
+
+mixin Mixin {
+  int? mixinField1;
+  int mixinField2 = 0;
+  int? mixinMethod(int i) {
+    super.toString();
+  }
+}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart
new file mode 100644
index 0000000..e1f91ac
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/opt_out_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+import 'opt_in_lib.dart';
+
+class SubClass extends Class with Mixin {}
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/test.options b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/test.options
new file mode 100644
index 0000000..c0f5433
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/test.options
@@ -0,0 +1,2 @@
+opt_in_lib.dart
+opt_out_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart
new file mode 100644
index 0000000..1c2249c
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/mixin_from_opt_in/test_lib.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'opt_out_lib.dart';
+
+test() {
+  SubClass sub = new SubClass();
+  int i = sub.classMethod(null);
+  int j = sub.mixinMethod(null);
+  sub.classField2 = sub.classField1;
+  sub.mixinField2 = sub.mixinField1;
+}
diff --git a/pkg/front_end/testcases/general/forwarding_semi_stub.dart b/pkg/front_end/testcases/general/forwarding_semi_stub.dart
new file mode 100644
index 0000000..9eb6cea
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_semi_stub.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Super<T> {
+  void method1(int a) {}
+  void method2({int? a}) {}
+  void method3(int a) {}
+  void method4(num a) {}
+  void method5({int? a}) {}
+  void method6({num? a}) {}
+  void method7(List<T> a) {}
+  void method8({List<T>? a}) {}
+  void method9(List<T> a) {}
+  void method10(Iterable<T> a) {}
+  void method11({List<T>? a}) {}
+  void method12({Iterable<T>? a}) {}
+
+  void set setter1(int a) {}
+  void set setter2(num a) {}
+  void set setter3(List<T> a) {}
+  void set setter4(Iterable<T> a) {}
+}
+
+class Interface<T> {
+  void method1(covariant num a) {}
+  void method2({covariant num? a}) {}
+  void method7(covariant Iterable<T> a) {}
+  void method8({covariant Iterable<T>? a}) {}
+
+  void set setter1(covariant num a) {}
+  void set setter3(covariant Iterable<T> a) {}
+}
+
+abstract class Class<T> extends Super<T> implements Interface<T> {
+  void method3(covariant num a);
+  void method4(covariant int a);
+  void method5({covariant num? a});
+  void method6({covariant int? a});
+
+  void method9(covariant Iterable<T> a);
+  void method10(covariant List<T> a);
+  void method11({covariant Iterable<T>? a});
+  void method12({covariant List<T>? a});
+
+  void set setter2(covariant int a);
+  void set setter4(covariant List<T> a);
+}
+
+class Subclass<T> extends Class<T> {
+  void method1(num a) {}
+  void method2({num? a}) {}
+  void method3(num a) {}
+  void method4(num a) {}
+  void method5({num? a}) {}
+  void method6({num? a}) {}
+  void method7(Iterable<T> a) {}
+  void method8({Iterable<T>? a}) {}
+  void method9(Iterable<T> a) {}
+  void method10(Iterable<T> a) {}
+  void method11({Iterable<T>? a}) {}
+  void method12({Iterable<T>? a}) {}
+
+  void set setter1(num a) {}
+  void set setter2(num a) {}
+  void set setter3(Iterable<T> a) {}
+  void set setter4(Iterable<T> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/forwarding_semi_stub.dart.textual_outline.expect b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.textual_outline.expect
new file mode 100644
index 0000000..4734da5
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.textual_outline.expect
@@ -0,0 +1,61 @@
+class Super<T> {
+  void method1(int a) {}
+  void method2({int? a}) {}
+  void method3(int a) {}
+  void method4(num a) {}
+  void method5({int? a}) {}
+  void method6({num? a}) {}
+  void method7(List<T> a) {}
+  void method8({List<T>? a}) {}
+  void method9(List<T> a) {}
+  void method10(Iterable<T> a) {}
+  void method11({List<T>? a}) {}
+  void method12({Iterable<T>? a}) {}
+  void set setter1(int a) {}
+  void set setter2(num a) {}
+  void set setter3(List<T> a) {}
+  void set setter4(Iterable<T> a) {}
+}
+
+class Interface<T> {
+  void method1(covariant num a) {}
+  void method2({covariant num? a}) {}
+  void method7(covariant Iterable<T> a) {}
+  void method8({covariant Iterable<T>? a}) {}
+  void set setter1(covariant num a) {}
+  void set setter3(covariant Iterable<T> a) {}
+}
+
+abstract class Class<T> extends Super<T> implements Interface<T> {
+  void method3(covariant num a);
+  void method4(covariant int a);
+  void method5({covariant num? a});
+  void method6({covariant int? a});
+  void method9(covariant Iterable<T> a);
+  void method10(covariant List<T> a);
+  void method11({covariant Iterable<T>? a});
+  void method12({covariant List<T>? a});
+  void set setter2(covariant int a);
+  void set setter4(covariant List<T> a);
+}
+
+class Subclass<T> extends Class<T> {
+  void method1(num a) {}
+  void method2({num? a}) {}
+  void method3(num a) {}
+  void method4(num a) {}
+  void method5({num? a}) {}
+  void method6({num? a}) {}
+  void method7(Iterable<T> a) {}
+  void method8({Iterable<T>? a}) {}
+  void method9(Iterable<T> a) {}
+  void method10(Iterable<T> a) {}
+  void method11({Iterable<T>? a}) {}
+  void method12({Iterable<T>? a}) {}
+  void set setter1(num a) {}
+  void set setter2(num a) {}
+  void set setter3(Iterable<T> a) {}
+  void set setter4(Iterable<T> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/forwarding_semi_stub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b5e8274c
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.textual_outline_modelled.expect
@@ -0,0 +1,61 @@
+abstract class Class<T> extends Super<T> implements Interface<T> {
+  void method10(covariant List<T> a);
+  void method11({covariant Iterable<T>? a});
+  void method12({covariant List<T>? a});
+  void method3(covariant num a);
+  void method4(covariant int a);
+  void method5({covariant num? a});
+  void method6({covariant int? a});
+  void method9(covariant Iterable<T> a);
+  void set setter2(covariant int a);
+  void set setter4(covariant List<T> a);
+}
+
+class Interface<T> {
+  void method1(covariant num a) {}
+  void method2({covariant num? a}) {}
+  void method7(covariant Iterable<T> a) {}
+  void method8({covariant Iterable<T>? a}) {}
+  void set setter1(covariant num a) {}
+  void set setter3(covariant Iterable<T> a) {}
+}
+
+class Subclass<T> extends Class<T> {
+  void method1(num a) {}
+  void method10(Iterable<T> a) {}
+  void method11({Iterable<T>? a}) {}
+  void method12({Iterable<T>? a}) {}
+  void method2({num? a}) {}
+  void method3(num a) {}
+  void method4(num a) {}
+  void method5({num? a}) {}
+  void method6({num? a}) {}
+  void method7(Iterable<T> a) {}
+  void method8({Iterable<T>? a}) {}
+  void method9(Iterable<T> a) {}
+  void set setter1(num a) {}
+  void set setter2(num a) {}
+  void set setter3(Iterable<T> a) {}
+  void set setter4(Iterable<T> a) {}
+}
+
+class Super<T> {
+  void method1(int a) {}
+  void method10(Iterable<T> a) {}
+  void method11({List<T>? a}) {}
+  void method12({Iterable<T>? a}) {}
+  void method2({int? a}) {}
+  void method3(int a) {}
+  void method4(num a) {}
+  void method5({int? a}) {}
+  void method6({num? a}) {}
+  void method7(List<T> a) {}
+  void method8({List<T>? a}) {}
+  void method9(List<T> a) {}
+  void set setter1(int a) {}
+  void set setter2(num a) {}
+  void set setter3(List<T> a) {}
+  void set setter4(Iterable<T> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.expect b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.expect
new file mode 100644
index 0000000..f1523c5
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.expect
@@ -0,0 +1,99 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Super<self::Super::T%>
+    : super core::Object::•()
+    ;
+  method method1(core::int a) → void {}
+  method method2({core::int? a = #C1}) → void {}
+  method method3(core::int a) → void {}
+  method method4(core::num a) → void {}
+  method method5({core::int? a = #C1}) → void {}
+  method method6({core::num? a = #C1}) → void {}
+  method method7(covariant-by-class core::List<self::Super::T%> a) → void {}
+  method method8({covariant-by-class core::List<self::Super::T%>? a = #C1}) → void {}
+  method method9(covariant-by-class core::List<self::Super::T%> a) → void {}
+  method method10(covariant-by-class core::Iterable<self::Super::T%> a) → void {}
+  method method11({covariant-by-class core::List<self::Super::T%>? a = #C1}) → void {}
+  method method12({covariant-by-class core::Iterable<self::Super::T%>? a = #C1}) → void {}
+  set setter1(core::int a) → void {}
+  set setter2(core::num a) → void {}
+  set setter3(covariant-by-class core::List<self::Super::T%> a) → void {}
+  set setter4(covariant-by-class core::Iterable<self::Super::T%> a) → void {}
+}
+class Interface<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Interface<self::Interface::T%>
+    : super core::Object::•()
+    ;
+  method method1(covariant-by-declaration core::num a) → void {}
+  method method2({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> a) → void {}
+  method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%>? a = #C1}) → void {}
+  set setter1(covariant-by-declaration core::num a) → void {}
+  set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> a) → void {}
+}
+abstract class Class<T extends core::Object? = dynamic> extends self::Super<self::Class::T%> implements self::Interface<self::Class::T%> {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    : super self::Super::•()
+    ;
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::num) → void */ method3(covariant-by-declaration core::int a) → void
+    return super.{self::Super::method3}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method4(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method4}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::num?}) → void */ method5({covariant-by-declaration core::int? a = #C1}) → void
+    return super.{self::Super::method5}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::int?}) → void */ method6({covariant-by-declaration core::num? a = #C1}) → void
+    return super.{self::Super::method6}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::Iterable<self::Class::T%>) → void */ method9(covariant-by-declaration covariant-by-class core::List<self::Class::T%> a) → void
+    return super.{self::Super::method9}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::List<self::Class::T%>) → void */ method10(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method10}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::Iterable<self::Class::T%>?}) → void */ method11({covariant-by-declaration covariant-by-class core::List<self::Class::T%>? a = #C1}) → void
+    return super.{self::Super::method11}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::List<self::Class::T%>?}) → void */ method12({covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%>? a = #C1}) → void
+    return super.{self::Super::method12}(a: a);
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter2(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter2} = a;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::List<self::Class::T%>) → void */ setter4(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter4} = a;
+  forwarding-stub method method1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method1}(a as core::int);
+  forwarding-stub method method2({covariant-by-declaration core::num? a = #C1}) → void
+    return super.{self::Super::method2}(a: a as core::int?);
+  forwarding-stub method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method7}(a as core::List<self::Class::T%>);
+  forwarding-stub method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%>? a = #C1}) → void
+    return super.{self::Super::method8}(a: a as core::List<self::Class::T%>?);
+  forwarding-stub set setter1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter1} = a as core::int;
+  forwarding-stub set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter3} = a as core::List<self::Class::T%>;
+}
+class Subclass<T extends core::Object? = dynamic> extends self::Class<self::Subclass::T%> {
+  synthetic constructor •() → self::Subclass<self::Subclass::T%>
+    : super self::Class::•()
+    ;
+  method method1(covariant-by-declaration core::num a) → void {}
+  method method2({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method3(covariant-by-declaration core::num a) → void {}
+  method method4(covariant-by-declaration core::num a) → void {}
+  method method5({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method6({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a = #C1}) → void {}
+  method method9(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  method method10(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  method method11({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a = #C1}) → void {}
+  method method12({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a = #C1}) → void {}
+  set setter1(covariant-by-declaration core::num a) → void {}
+  set setter2(covariant-by-declaration core::num a) → void {}
+  set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  set setter4(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.outline.expect b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.outline.expect
new file mode 100644
index 0000000..413db05
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.outline.expect
@@ -0,0 +1,130 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Super<self::Super::T%>
+    ;
+  method method1(core::int a) → void
+    ;
+  method method2({core::int? a}) → void
+    ;
+  method method3(core::int a) → void
+    ;
+  method method4(core::num a) → void
+    ;
+  method method5({core::int? a}) → void
+    ;
+  method method6({core::num? a}) → void
+    ;
+  method method7(covariant-by-class core::List<self::Super::T%> a) → void
+    ;
+  method method8({covariant-by-class core::List<self::Super::T%>? a}) → void
+    ;
+  method method9(covariant-by-class core::List<self::Super::T%> a) → void
+    ;
+  method method10(covariant-by-class core::Iterable<self::Super::T%> a) → void
+    ;
+  method method11({covariant-by-class core::List<self::Super::T%>? a}) → void
+    ;
+  method method12({covariant-by-class core::Iterable<self::Super::T%>? a}) → void
+    ;
+  set setter1(core::int a) → void
+    ;
+  set setter2(core::num a) → void
+    ;
+  set setter3(covariant-by-class core::List<self::Super::T%> a) → void
+    ;
+  set setter4(covariant-by-class core::Iterable<self::Super::T%> a) → void
+    ;
+}
+class Interface<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Interface<self::Interface::T%>
+    ;
+  method method1(covariant-by-declaration core::num a) → void
+    ;
+  method method2({covariant-by-declaration core::num? a}) → void
+    ;
+  method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> a) → void
+    ;
+  method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%>? a}) → void
+    ;
+  set setter1(covariant-by-declaration core::num a) → void
+    ;
+  set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> a) → void
+    ;
+}
+abstract class Class<T extends core::Object? = dynamic> extends self::Super<self::Class::T%> implements self::Interface<self::Class::T%> {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    ;
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::num) → void */ method3(covariant-by-declaration core::int a) → void
+    return super.{self::Super::method3}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method4(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method4}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::num?}) → void */ method5({covariant-by-declaration core::int? a}) → void
+    return super.{self::Super::method5}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::int?}) → void */ method6({covariant-by-declaration core::num? a}) → void
+    return super.{self::Super::method6}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::Iterable<self::Class::T%>) → void */ method9(covariant-by-declaration covariant-by-class core::List<self::Class::T%> a) → void
+    return super.{self::Super::method9}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::List<self::Class::T%>) → void */ method10(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method10}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::Iterable<self::Class::T%>?}) → void */ method11({covariant-by-declaration covariant-by-class core::List<self::Class::T%>? a}) → void
+    return super.{self::Super::method11}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::List<self::Class::T%>?}) → void */ method12({covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%>? a}) → void
+    return super.{self::Super::method12}(a: a);
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter2(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter2} = a;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::List<self::Class::T%>) → void */ setter4(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter4} = a;
+  forwarding-stub method method1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method1}(a as core::int);
+  forwarding-stub method method2({covariant-by-declaration core::num? a}) → void
+    return super.{self::Super::method2}(a: a as core::int?);
+  forwarding-stub method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method7}(a as core::List<self::Class::T%>);
+  forwarding-stub method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%>? a}) → void
+    return super.{self::Super::method8}(a: a as core::List<self::Class::T%>?);
+  forwarding-stub set setter1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter1} = a as core::int;
+  forwarding-stub set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter3} = a as core::List<self::Class::T%>;
+}
+class Subclass<T extends core::Object? = dynamic> extends self::Class<self::Subclass::T%> {
+  synthetic constructor •() → self::Subclass<self::Subclass::T%>
+    ;
+  method method1(covariant-by-declaration core::num a) → void
+    ;
+  method method2({covariant-by-declaration core::num? a}) → void
+    ;
+  method method3(covariant-by-declaration core::num a) → void
+    ;
+  method method4(covariant-by-declaration core::num a) → void
+    ;
+  method method5({covariant-by-declaration core::num? a}) → void
+    ;
+  method method6({covariant-by-declaration core::num? a}) → void
+    ;
+  method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void
+    ;
+  method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a}) → void
+    ;
+  method method9(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void
+    ;
+  method method10(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void
+    ;
+  method method11({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a}) → void
+    ;
+  method method12({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a}) → void
+    ;
+  set setter1(covariant-by-declaration core::num a) → void
+    ;
+  set setter2(covariant-by-declaration core::num a) → void
+    ;
+  set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void
+    ;
+  set setter4(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.transformed.expect b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.transformed.expect
new file mode 100644
index 0000000..f1523c5
--- /dev/null
+++ b/pkg/front_end/testcases/general/forwarding_semi_stub.dart.weak.transformed.expect
@@ -0,0 +1,99 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Super<self::Super::T%>
+    : super core::Object::•()
+    ;
+  method method1(core::int a) → void {}
+  method method2({core::int? a = #C1}) → void {}
+  method method3(core::int a) → void {}
+  method method4(core::num a) → void {}
+  method method5({core::int? a = #C1}) → void {}
+  method method6({core::num? a = #C1}) → void {}
+  method method7(covariant-by-class core::List<self::Super::T%> a) → void {}
+  method method8({covariant-by-class core::List<self::Super::T%>? a = #C1}) → void {}
+  method method9(covariant-by-class core::List<self::Super::T%> a) → void {}
+  method method10(covariant-by-class core::Iterable<self::Super::T%> a) → void {}
+  method method11({covariant-by-class core::List<self::Super::T%>? a = #C1}) → void {}
+  method method12({covariant-by-class core::Iterable<self::Super::T%>? a = #C1}) → void {}
+  set setter1(core::int a) → void {}
+  set setter2(core::num a) → void {}
+  set setter3(covariant-by-class core::List<self::Super::T%> a) → void {}
+  set setter4(covariant-by-class core::Iterable<self::Super::T%> a) → void {}
+}
+class Interface<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Interface<self::Interface::T%>
+    : super core::Object::•()
+    ;
+  method method1(covariant-by-declaration core::num a) → void {}
+  method method2({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> a) → void {}
+  method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%>? a = #C1}) → void {}
+  set setter1(covariant-by-declaration core::num a) → void {}
+  set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> a) → void {}
+}
+abstract class Class<T extends core::Object? = dynamic> extends self::Super<self::Class::T%> implements self::Interface<self::Class::T%> {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    : super self::Super::•()
+    ;
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::num) → void */ method3(covariant-by-declaration core::int a) → void
+    return super.{self::Super::method3}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method4(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method4}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::num?}) → void */ method5({covariant-by-declaration core::int? a = #C1}) → void
+    return super.{self::Super::method5}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::int?}) → void */ method6({covariant-by-declaration core::num? a = #C1}) → void
+    return super.{self::Super::method6}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::Iterable<self::Class::T%>) → void */ method9(covariant-by-declaration covariant-by-class core::List<self::Class::T%> a) → void
+    return super.{self::Super::method9}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::List<self::Class::T%>) → void */ method10(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method10}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::Iterable<self::Class::T%>?}) → void */ method11({covariant-by-declaration covariant-by-class core::List<self::Class::T%>? a = #C1}) → void
+    return super.{self::Super::method11}(a: a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: ({a: core::List<self::Class::T%>?}) → void */ method12({covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%>? a = #C1}) → void
+    return super.{self::Super::method12}(a: a);
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter2(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter2} = a;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::List<self::Class::T%>) → void */ setter4(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter4} = a;
+  forwarding-stub method method1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method1}(a as core::int);
+  forwarding-stub method method2({covariant-by-declaration core::num? a = #C1}) → void
+    return super.{self::Super::method2}(a: a as core::int?);
+  forwarding-stub method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method7}(a as core::List<self::Class::T%>);
+  forwarding-stub method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%>? a = #C1}) → void
+    return super.{self::Super::method8}(a: a as core::List<self::Class::T%>?);
+  forwarding-stub set setter1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter1} = a as core::int;
+  forwarding-stub set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter3} = a as core::List<self::Class::T%>;
+}
+class Subclass<T extends core::Object? = dynamic> extends self::Class<self::Subclass::T%> {
+  synthetic constructor •() → self::Subclass<self::Subclass::T%>
+    : super self::Class::•()
+    ;
+  method method1(covariant-by-declaration core::num a) → void {}
+  method method2({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method3(covariant-by-declaration core::num a) → void {}
+  method method4(covariant-by-declaration core::num a) → void {}
+  method method5({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method6({covariant-by-declaration core::num? a = #C1}) → void {}
+  method method7(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  method method8({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a = #C1}) → void {}
+  method method9(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  method method10(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  method method11({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a = #C1}) → void {}
+  method method12({covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%>? a = #C1}) → void {}
+  set setter1(covariant-by-declaration core::num a) → void {}
+  set setter2(covariant-by-declaration core::num a) → void {}
+  set setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+  set setter4(covariant-by-declaration covariant-by-class core::Iterable<self::Subclass::T%> a) → void {}
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart
index 3f83073..c3dcc28 100644
--- a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart
@@ -1,7 +1,9 @@
 // Copyright (c) 2019, 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.9
+
 //------------------------------------------------------------------------------
 
 class A {
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.expect b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.expect
index 04d5bc5..6b4bf1c 100644
--- a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.expect
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.expect
@@ -73,7 +73,7 @@
   synthetic constructor •() → self::E*
     : super self::D::•()
     ;
-  forwarding-stub forwarding-semi-stub operator +(covariant-by-declaration core::int* e) → dynamic
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (core::int*) →* dynamic */ +(covariant-by-declaration dynamic e) → dynamic
     return super.{self::D::+}(e);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.outline.expect b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.outline.expect
index b2f74cc..15ab476 100644
--- a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.outline.expect
@@ -68,7 +68,7 @@
 class E extends self::D {
   synthetic constructor •() → self::E*
     ;
-  forwarding-stub forwarding-semi-stub operator +(covariant-by-declaration core::int* e) → dynamic
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (core::int*) →* dynamic */ +(covariant-by-declaration dynamic e) → dynamic
     return super.{self::D::+}(e);
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.transformed.expect b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.transformed.expect
index 04d5bc5..6b4bf1c 100644
--- a/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/forwarding_stub_for_operator.dart.weak.transformed.expect
@@ -73,7 +73,7 @@
   synthetic constructor •() → self::E*
     : super self::D::•()
     ;
-  forwarding-stub forwarding-semi-stub operator +(covariant-by-declaration core::int* e) → dynamic
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (core::int*) →* dynamic */ +(covariant-by-declaration dynamic e) → dynamic
     return super.{self::D::+}(e);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/implement_semi_stub.dart b/pkg/front_end/testcases/general/implement_semi_stub.dart
new file mode 100644
index 0000000..9ce9099
--- /dev/null
+++ b/pkg/front_end/testcases/general/implement_semi_stub.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Super<T> {
+  void method1(num a) {}
+  void method2(int b) {}
+  void method3(num a, int b) {}
+  void method4({required num a}) {}
+  void method5({required int b}) {}
+  //void method6({required num a, required int b}) {}
+  void method7(Iterable<T> a) {}
+  void method8(List<T> b) {}
+  void method9(Iterable<T> a, List<T> b) {}
+  void method10({required Iterable<T> a}) {}
+  void method11({required List<T> b}) {}
+  //void method12({required Iterable<T> a, required List<T> b}) {}
+
+  void set setter1(num a) {}
+  //void set setter2(int a) {}
+  void set setter3(Iterable<T> a) {}
+  //void set setter4(List<T> a) {}
+}
+
+abstract class Interface<T> {
+  void method2(covariant num b) {}
+  void method3(num a, covariant num b) {}
+  void method5({required int b}) {}
+  //void method6({required num a, required covariant num b}) {}
+  void method8(covariant Iterable<T> b) {}
+  void method9(Iterable<T> a, covariant Iterable<T> b) {}
+  void method11({required List<T> b}) {}
+  //void method12({required Iterable<T> a, required covariant Iterable<T> b}) {}
+  //void set setter2(covariant num a) {}
+  //void set setter4(covariant Iterable<T> a) {}
+}
+
+class Class<T> extends Super<T> implements Interface<T> {
+  void method1(covariant int a);
+  void method2(num b);
+  void method3(covariant int a, num b);
+  void method7(covariant List<T> a);
+  void method8(Iterable<T> b);
+  void method9(covariant List<T> a, Iterable<T> b);
+  void set setter1(covariant int a);
+  //void set setter2(num a);
+  void set setter3(covariant List<T> a);
+  //void set setter4(Iterable<T> a);
+}
+
+class Class1<T> implements Class<T> {
+  void method1(double a) {} // error
+  void method2(double b) {} // error
+  void method3(double a, double b) {} // error
+  void method4({required double a}) {} // error
+  void method5({required double b}) {} // error
+  //void method6({required double a, required double b}) {} // error
+  void method7(Set<T> a) {} // error
+  void method8(Set<T> b) {} // error
+  void method9(Set<T> a, Set<T> b) {} // error
+  void method10({required Set<T> a}) {} // error
+  void method11({required Set<T> b}) {} // error
+  //void method12({required Set<T> a, required Set<T> b}) {} // error
+  void set setter1(double a) {} // error
+  //void set setter2(double a) {} // error
+  void set setter3(Set<T> a) {} // error
+  //void set setter4(Set<T> a) {} // error
+}
+
+abstract class Interface2<T> {
+  void method1(int a);
+  void method2(int b);
+  void method3(int a, int b);
+  void method7(List<T> a);
+  void method8(List<T> b);
+  void method9(List<T> a, List<T> b);
+  void set setter1(int a);
+  //void set setter2(int a);
+  void set setter3(List<T> a);
+  //void set setter4(List<T> a);
+}
+
+abstract class Class2<T> implements Class<T>, Interface2<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implement_semi_stub.dart.textual_outline.expect b/pkg/front_end/testcases/general/implement_semi_stub.dart.textual_outline.expect
new file mode 100644
index 0000000..526b06a
--- /dev/null
+++ b/pkg/front_end/testcases/general/implement_semi_stub.dart.textual_outline.expect
@@ -0,0 +1,64 @@
+class Super<T> {
+  void method1(num a) {}
+  void method2(int b) {}
+  void method3(num a, int b) {}
+  void method4({required num a}) {}
+  void method5({required int b}) {}
+  void method7(Iterable<T> a) {}
+  void method8(List<T> b) {}
+  void method9(Iterable<T> a, List<T> b) {}
+  void method10({required Iterable<T> a}) {}
+  void method11({required List<T> b}) {}
+  void set setter1(num a) {}
+  void set setter3(Iterable<T> a) {}
+}
+
+abstract class Interface<T> {
+  void method2(covariant num b) {}
+  void method3(num a, covariant num b) {}
+  void method5({required int b}) {}
+  void method8(covariant Iterable<T> b) {}
+  void method9(Iterable<T> a, covariant Iterable<T> b) {}
+  void method11({required List<T> b}) {}
+}
+
+class Class<T> extends Super<T> implements Interface<T> {
+  void method1(covariant int a);
+  void method2(num b);
+  void method3(covariant int a, num b);
+  void method7(covariant List<T> a);
+  void method8(Iterable<T> b);
+  void method9(covariant List<T> a, Iterable<T> b);
+  void set setter1(covariant int a);
+  void set setter3(covariant List<T> a);
+}
+
+class Class1<T> implements Class<T> {
+  void method1(double a) {}
+  void method2(double b) {}
+  void method3(double a, double b) {}
+  void method4({required double a}) {}
+  void method5({required double b}) {}
+  void method7(Set<T> a) {}
+  void method8(Set<T> b) {}
+  void method9(Set<T> a, Set<T> b) {}
+  void method10({required Set<T> a}) {}
+  void method11({required Set<T> b}) {}
+  void set setter1(double a) {}
+  void set setter3(Set<T> a) {}
+}
+
+abstract class Interface2<T> {
+  void method1(int a);
+  void method2(int b);
+  void method3(int a, int b);
+  void method7(List<T> a);
+  void method8(List<T> b);
+  void method9(List<T> a, List<T> b);
+  void set setter1(int a);
+  void set setter3(List<T> a);
+}
+
+abstract class Class2<T> implements Class<T>, Interface2<T> {}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implement_semi_stub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/implement_semi_stub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c019748
--- /dev/null
+++ b/pkg/front_end/testcases/general/implement_semi_stub.dart.textual_outline_modelled.expect
@@ -0,0 +1,64 @@
+abstract class Class2<T> implements Class<T>, Interface2<T> {}
+
+abstract class Interface<T> {
+  void method11({required List<T> b}) {}
+  void method2(covariant num b) {}
+  void method3(num a, covariant num b) {}
+  void method5({required int b}) {}
+  void method8(covariant Iterable<T> b) {}
+  void method9(Iterable<T> a, covariant Iterable<T> b) {}
+}
+
+abstract class Interface2<T> {
+  void method1(int a);
+  void method2(int b);
+  void method3(int a, int b);
+  void method7(List<T> a);
+  void method8(List<T> b);
+  void method9(List<T> a, List<T> b);
+  void set setter1(int a);
+  void set setter3(List<T> a);
+}
+
+class Class<T> extends Super<T> implements Interface<T> {
+  void method1(covariant int a);
+  void method2(num b);
+  void method3(covariant int a, num b);
+  void method7(covariant List<T> a);
+  void method8(Iterable<T> b);
+  void method9(covariant List<T> a, Iterable<T> b);
+  void set setter1(covariant int a);
+  void set setter3(covariant List<T> a);
+}
+
+class Class1<T> implements Class<T> {
+  void method1(double a) {}
+  void method10({required Set<T> a}) {}
+  void method11({required Set<T> b}) {}
+  void method2(double b) {}
+  void method3(double a, double b) {}
+  void method4({required double a}) {}
+  void method5({required double b}) {}
+  void method7(Set<T> a) {}
+  void method8(Set<T> b) {}
+  void method9(Set<T> a, Set<T> b) {}
+  void set setter1(double a) {}
+  void set setter3(Set<T> a) {}
+}
+
+class Super<T> {
+  void method1(num a) {}
+  void method10({required Iterable<T> a}) {}
+  void method11({required List<T> b}) {}
+  void method2(int b) {}
+  void method3(num a, int b) {}
+  void method4({required num a}) {}
+  void method5({required int b}) {}
+  void method7(Iterable<T> a) {}
+  void method8(List<T> b) {}
+  void method9(Iterable<T> a, List<T> b) {}
+  void set setter1(num a) {}
+  void set setter3(Iterable<T> a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/implement_semi_stub.dart.weak.expect b/pkg/front_end/testcases/general/implement_semi_stub.dart.weak.expect
new file mode 100644
index 0000000..e8b7608
--- /dev/null
+++ b/pkg/front_end/testcases/general/implement_semi_stub.dart.weak.expect
@@ -0,0 +1,222 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:52:23: Error: The parameter 'a' of the method 'Class1.method1' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Class.method1'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method1(double a) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:39:8: Context: This is the overridden method ('method1').
+//   void method1(covariant int a);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:53:23: Error: The parameter 'b' of the method 'Class1.method2' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Super.method2'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method2(double b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:7:8: Context: This is the overridden method ('method2').
+//   void method2(int b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:54:23: Error: The parameter 'a' of the method 'Class1.method3' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Class.method3'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method3(double a, double b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:41:8: Context: This is the overridden method ('method3').
+//   void method3(covariant int a, num b);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:54:33: Error: The parameter 'b' of the method 'Class1.method3' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Super.method3'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method3(double a, double b) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:8:8: Context: This is the overridden method ('method3').
+//   void method3(num a, int b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:55:33: Error: The parameter 'a' of the method 'Class1.method4' has type 'double', which does not match the corresponding type, 'num', in the overridden method, 'Super.method4'.
+// Change to a supertype of 'num', or, for a covariant parameter, a subtype.
+//   void method4({required double a}) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:9:8: Context: This is the overridden method ('method4').
+//   void method4({required num a}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:56:33: Error: The parameter 'b' of the method 'Class1.method5' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Super.method5'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method5({required double b}) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:10:8: Context: This is the overridden method ('method5').
+//   void method5({required int b}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:58:23: Error: The parameter 'a' of the method 'Class1.method7' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Class.method7'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method7(Set<T> a) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:42:8: Context: This is the overridden method ('method7').
+//   void method7(covariant List<T> a);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:59:23: Error: The parameter 'b' of the method 'Class1.method8' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Super.method8'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method8(Set<T> b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:13:8: Context: This is the overridden method ('method8').
+//   void method8(List<T> b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:60:23: Error: The parameter 'a' of the method 'Class1.method9' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Class.method9'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method9(Set<T> a, Set<T> b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:44:8: Context: This is the overridden method ('method9').
+//   void method9(covariant List<T> a, Iterable<T> b);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:60:33: Error: The parameter 'b' of the method 'Class1.method9' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Super.method9'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method9(Set<T> a, Set<T> b) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:14:8: Context: This is the overridden method ('method9').
+//   void method9(Iterable<T> a, List<T> b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:61:34: Error: The parameter 'a' of the method 'Class1.method10' has type 'Set<T>', which does not match the corresponding type, 'Iterable<T>', in the overridden method, 'Super.method10'.
+//  - 'Set' is from 'dart:core'.
+//  - 'Iterable' is from 'dart:core'.
+// Change to a supertype of 'Iterable<T>', or, for a covariant parameter, a subtype.
+//   void method10({required Set<T> a}) {} // error
+//                                  ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:15:8: Context: This is the overridden method ('method10').
+//   void method10({required Iterable<T> a}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:62:34: Error: The parameter 'b' of the method 'Class1.method11' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Super.method11'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method11({required Set<T> b}) {} // error
+//                                  ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:16:8: Context: This is the overridden method ('method11').
+//   void method11({required List<T> b}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:64:27: Error: The parameter 'a' of the method 'Class1.setter1' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Class.setter1'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void set setter1(double a) {} // error
+//                           ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:45:12: Context: This is the overridden method ('setter1').
+//   void set setter1(covariant int a);
+//            ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:66:27: Error: The parameter 'a' of the method 'Class1.setter3' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Class.setter3'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void set setter3(Set<T> a) {} // error
+//                           ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:47:12: Context: This is the overridden method ('setter3').
+//   void set setter3(covariant List<T> a);
+//            ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Super<self::Super::T%>
+    : super core::Object::•()
+    ;
+  method method1(core::num a) → void {}
+  method method2(core::int b) → void {}
+  method method3(core::num a, core::int b) → void {}
+  method method4({required core::num a = #C1}) → void {}
+  method method5({required core::int b = #C1}) → void {}
+  method method7(covariant-by-class core::Iterable<self::Super::T%> a) → void {}
+  method method8(covariant-by-class core::List<self::Super::T%> b) → void {}
+  method method9(covariant-by-class core::Iterable<self::Super::T%> a, covariant-by-class core::List<self::Super::T%> b) → void {}
+  method method10({required covariant-by-class core::Iterable<self::Super::T%> a = #C1}) → void {}
+  method method11({required covariant-by-class core::List<self::Super::T%> b = #C1}) → void {}
+  set setter1(core::num a) → void {}
+  set setter3(covariant-by-class core::Iterable<self::Super::T%> a) → void {}
+}
+abstract class Interface<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Interface<self::Interface::T%>
+    : super core::Object::•()
+    ;
+  method method2(covariant-by-declaration core::num b) → void {}
+  method method3(core::num a, covariant-by-declaration core::num b) → void {}
+  method method5({required core::int b = #C1}) → void {}
+  method method8(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> b) → void {}
+  method method9(covariant-by-class core::Iterable<self::Interface::T%> a, covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> b) → void {}
+  method method11({required covariant-by-class core::List<self::Interface::T%> b = #C1}) → void {}
+}
+class Class<T extends core::Object? = dynamic> extends self::Super<self::Class::T%> implements self::Interface<self::Class::T%> {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    : super self::Super::•()
+    ;
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method1}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::num) → void */ method2(covariant-by-declaration core::int b) → void
+    return super.{self::Super::method2}(b);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int, core::num) → void */ method3(covariant-by-declaration core::num a, covariant-by-declaration core::int b) → void
+    return super.{self::Super::method3}(a, b);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::List<self::Class::T%>) → void */ method7(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method7}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::Iterable<self::Class::T%>) → void */ method8(covariant-by-declaration covariant-by-class core::List<self::Class::T%> b) → void
+    return super.{self::Super::method8}(b);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::List<self::Class::T%>, core::Iterable<self::Class::T%>) → void */ method9(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a, covariant-by-declaration covariant-by-class core::List<self::Class::T%> b) → void
+    return super.{self::Super::method9}(a, b);
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter1} = a;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::List<self::Class::T%>) → void */ setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter3} = a;
+}
+class Class1<T extends core::Object? = dynamic> extends core::Object implements self::Class<self::Class1::T%> {
+  synthetic constructor •() → self::Class1<self::Class1::T%>
+    : super core::Object::•()
+    ;
+  method method1(covariant-by-declaration core::double a) → void {}
+  method method2(covariant-by-declaration core::double b) → void {}
+  method method3(covariant-by-declaration core::double a, covariant-by-declaration core::double b) → void {}
+  method method4({required core::double a = #C1}) → void {}
+  method method5({required core::double b = #C1}) → void {}
+  method method7(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> a) → void {}
+  method method8(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> b) → void {}
+  method method9(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> a, covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> b) → void {}
+  method method10({required covariant-by-class core::Set<self::Class1::T%> a = #C1}) → void {}
+  method method11({required covariant-by-class core::Set<self::Class1::T%> b = #C1}) → void {}
+  set setter1(covariant-by-declaration core::double a) → void {}
+  set setter3(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> a) → void {}
+}
+abstract class Interface2<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Interface2<self::Interface2::T%>
+    : super core::Object::•()
+    ;
+  abstract method method1(core::int a) → void;
+  abstract method method2(core::int b) → void;
+  abstract method method3(core::int a, core::int b) → void;
+  abstract method method7(covariant-by-class core::List<self::Interface2::T%> a) → void;
+  abstract method method8(covariant-by-class core::List<self::Interface2::T%> b) → void;
+  abstract method method9(covariant-by-class core::List<self::Interface2::T%> a, covariant-by-class core::List<self::Interface2::T%> b) → void;
+  abstract set setter1(core::int a) → void;
+  abstract set setter3(covariant-by-class core::List<self::Interface2::T%> a) → void;
+}
+abstract class Class2<T extends core::Object? = dynamic> extends core::Object implements self::Class<self::Class2::T%>, self::Interface2<self::Class2::T%> {
+  synthetic constructor •() → self::Class2<self::Class2::T%>
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
+
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/implement_semi_stub.dart.weak.outline.expect b/pkg/front_end/testcases/general/implement_semi_stub.dart.weak.outline.expect
new file mode 100644
index 0000000..a5176a6
--- /dev/null
+++ b/pkg/front_end/testcases/general/implement_semi_stub.dart.weak.outline.expect
@@ -0,0 +1,243 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:52:23: Error: The parameter 'a' of the method 'Class1.method1' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Class.method1'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method1(double a) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:39:8: Context: This is the overridden method ('method1').
+//   void method1(covariant int a);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:53:23: Error: The parameter 'b' of the method 'Class1.method2' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Super.method2'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method2(double b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:7:8: Context: This is the overridden method ('method2').
+//   void method2(int b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:54:23: Error: The parameter 'a' of the method 'Class1.method3' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Class.method3'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method3(double a, double b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:41:8: Context: This is the overridden method ('method3').
+//   void method3(covariant int a, num b);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:54:33: Error: The parameter 'b' of the method 'Class1.method3' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Super.method3'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method3(double a, double b) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:8:8: Context: This is the overridden method ('method3').
+//   void method3(num a, int b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:55:33: Error: The parameter 'a' of the method 'Class1.method4' has type 'double', which does not match the corresponding type, 'num', in the overridden method, 'Super.method4'.
+// Change to a supertype of 'num', or, for a covariant parameter, a subtype.
+//   void method4({required double a}) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:9:8: Context: This is the overridden method ('method4').
+//   void method4({required num a}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:56:33: Error: The parameter 'b' of the method 'Class1.method5' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Super.method5'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void method5({required double b}) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:10:8: Context: This is the overridden method ('method5').
+//   void method5({required int b}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:58:23: Error: The parameter 'a' of the method 'Class1.method7' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Class.method7'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method7(Set<T> a) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:42:8: Context: This is the overridden method ('method7').
+//   void method7(covariant List<T> a);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:59:23: Error: The parameter 'b' of the method 'Class1.method8' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Super.method8'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method8(Set<T> b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:13:8: Context: This is the overridden method ('method8').
+//   void method8(List<T> b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:60:23: Error: The parameter 'a' of the method 'Class1.method9' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Class.method9'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method9(Set<T> a, Set<T> b) {} // error
+//                       ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:44:8: Context: This is the overridden method ('method9').
+//   void method9(covariant List<T> a, Iterable<T> b);
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:60:33: Error: The parameter 'b' of the method 'Class1.method9' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Super.method9'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method9(Set<T> a, Set<T> b) {} // error
+//                                 ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:14:8: Context: This is the overridden method ('method9').
+//   void method9(Iterable<T> a, List<T> b) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:61:34: Error: The parameter 'a' of the method 'Class1.method10' has type 'Set<T>', which does not match the corresponding type, 'Iterable<T>', in the overridden method, 'Super.method10'.
+//  - 'Set' is from 'dart:core'.
+//  - 'Iterable' is from 'dart:core'.
+// Change to a supertype of 'Iterable<T>', or, for a covariant parameter, a subtype.
+//   void method10({required Set<T> a}) {} // error
+//                                  ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:15:8: Context: This is the overridden method ('method10').
+//   void method10({required Iterable<T> a}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:62:34: Error: The parameter 'b' of the method 'Class1.method11' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Super.method11'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void method11({required Set<T> b}) {} // error
+//                                  ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:16:8: Context: This is the overridden method ('method11').
+//   void method11({required List<T> b}) {}
+//        ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:64:27: Error: The parameter 'a' of the method 'Class1.setter1' has type 'double', which does not match the corresponding type, 'int', in the overridden method, 'Class.setter1'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//   void set setter1(double a) {} // error
+//                           ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:45:12: Context: This is the overridden method ('setter1').
+//   void set setter1(covariant int a);
+//            ^
+//
+// pkg/front_end/testcases/general/implement_semi_stub.dart:66:27: Error: The parameter 'a' of the method 'Class1.setter3' has type 'Set<T>', which does not match the corresponding type, 'List<T>', in the overridden method, 'Class.setter3'.
+//  - 'Set' is from 'dart:core'.
+//  - 'List' is from 'dart:core'.
+// Change to a supertype of 'List<T>', or, for a covariant parameter, a subtype.
+//   void set setter3(Set<T> a) {} // error
+//                           ^
+// pkg/front_end/testcases/general/implement_semi_stub.dart:47:12: Context: This is the overridden method ('setter3').
+//   void set setter3(covariant List<T> a);
+//            ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Super<self::Super::T%>
+    ;
+  method method1(core::num a) → void
+    ;
+  method method2(core::int b) → void
+    ;
+  method method3(core::num a, core::int b) → void
+    ;
+  method method4({required core::num a}) → void
+    ;
+  method method5({required core::int b}) → void
+    ;
+  method method7(covariant-by-class core::Iterable<self::Super::T%> a) → void
+    ;
+  method method8(covariant-by-class core::List<self::Super::T%> b) → void
+    ;
+  method method9(covariant-by-class core::Iterable<self::Super::T%> a, covariant-by-class core::List<self::Super::T%> b) → void
+    ;
+  method method10({required covariant-by-class core::Iterable<self::Super::T%> a}) → void
+    ;
+  method method11({required covariant-by-class core::List<self::Super::T%> b}) → void
+    ;
+  set setter1(core::num a) → void
+    ;
+  set setter3(covariant-by-class core::Iterable<self::Super::T%> a) → void
+    ;
+}
+abstract class Interface<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Interface<self::Interface::T%>
+    ;
+  method method2(covariant-by-declaration core::num b) → void
+    ;
+  method method3(core::num a, covariant-by-declaration core::num b) → void
+    ;
+  method method5({required core::int b}) → void
+    ;
+  method method8(covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> b) → void
+    ;
+  method method9(covariant-by-class core::Iterable<self::Interface::T%> a, covariant-by-declaration covariant-by-class core::Iterable<self::Interface::T%> b) → void
+    ;
+  method method11({required covariant-by-class core::List<self::Interface::T%> b}) → void
+    ;
+}
+class Class<T extends core::Object? = dynamic> extends self::Super<self::Class::T%> implements self::Interface<self::Class::T%> {
+  synthetic constructor •() → self::Class<self::Class::T%>
+    ;
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method1}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::num) → void */ method2(covariant-by-declaration core::int b) → void
+    return super.{self::Super::method2}(b);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int, core::num) → void */ method3(covariant-by-declaration core::num a, covariant-by-declaration core::int b) → void
+    return super.{self::Super::method3}(a, b);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::List<self::Class::T%>) → void */ method7(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::method7}(a);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::Iterable<self::Class::T%>) → void */ method8(covariant-by-declaration covariant-by-class core::List<self::Class::T%> b) → void
+    return super.{self::Super::method8}(b);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::List<self::Class::T%>, core::Iterable<self::Class::T%>) → void */ method9(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a, covariant-by-declaration covariant-by-class core::List<self::Class::T%> b) → void
+    return super.{self::Super::method9}(a, b);
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter1(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter1} = a;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::List<self::Class::T%>) → void */ setter3(covariant-by-declaration covariant-by-class core::Iterable<self::Class::T%> a) → void
+    return super.{self::Super::setter3} = a;
+}
+class Class1<T extends core::Object? = dynamic> extends core::Object implements self::Class<self::Class1::T%> {
+  synthetic constructor •() → self::Class1<self::Class1::T%>
+    ;
+  method method1(covariant-by-declaration core::double a) → void
+    ;
+  method method2(covariant-by-declaration core::double b) → void
+    ;
+  method method3(covariant-by-declaration core::double a, covariant-by-declaration core::double b) → void
+    ;
+  method method4({required core::double a}) → void
+    ;
+  method method5({required core::double b}) → void
+    ;
+  method method7(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> a) → void
+    ;
+  method method8(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> b) → void
+    ;
+  method method9(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> a, covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> b) → void
+    ;
+  method method10({required covariant-by-class core::Set<self::Class1::T%> a}) → void
+    ;
+  method method11({required covariant-by-class core::Set<self::Class1::T%> b}) → void
+    ;
+  set setter1(covariant-by-declaration core::double a) → void
+    ;
+  set setter3(covariant-by-declaration covariant-by-class core::Set<self::Class1::T%> a) → void
+    ;
+}
+abstract class Interface2<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Interface2<self::Interface2::T%>
+    ;
+  abstract method method1(core::int a) → void;
+  abstract method method2(core::int b) → void;
+  abstract method method3(core::int a, core::int b) → void;
+  abstract method method7(covariant-by-class core::List<self::Interface2::T%> a) → void;
+  abstract method method8(covariant-by-class core::List<self::Interface2::T%> b) → void;
+  abstract method method9(covariant-by-class core::List<self::Interface2::T%> a, covariant-by-class core::List<self::Interface2::T%> b) → void;
+  abstract set setter1(core::int a) → void;
+  abstract set setter3(covariant-by-class core::List<self::Interface2::T%> a) → void;
+}
+abstract class Class2<T extends core::Object? = dynamic> extends core::Object implements self::Class<self::Class2::T%>, self::Interface2<self::Class2::T%> {
+  synthetic constructor •() → self::Class2<self::Class2::T%>
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.weak.expect b/pkg/front_end/testcases/general/issue47013b.dart.weak.expect
index 70fa41f..7ab0301 100644
--- a/pkg/front_end/testcases/general/issue47013b.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue47013b.dart.weak.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  forwarding-stub forwarding-semi-stub method m(covariant-by-declaration core::int i) → void
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ m(covariant-by-declaration core::num i) → void
     return super.{self::A::m}(i);
 }
 class C extends self::B {
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47013b.dart.weak.outline.expect
index 81997e1..132d880 100644
--- a/pkg/front_end/testcases/general/issue47013b.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/issue47013b.dart.weak.outline.expect
@@ -11,7 +11,7 @@
 class B extends self::A {
   synthetic constructor •() → self::B
     ;
-  forwarding-stub forwarding-semi-stub method m(covariant-by-declaration core::int i) → void
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ m(covariant-by-declaration core::num i) → void
     return super.{self::A::m}(i);
 }
 class C extends self::B {
diff --git a/pkg/front_end/testcases/general/issue47013b.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47013b.dart.weak.transformed.expect
index 70fa41f..7ab0301 100644
--- a/pkg/front_end/testcases/general/issue47013b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue47013b.dart.weak.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  forwarding-stub forwarding-semi-stub method m(covariant-by-declaration core::int i) → void
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ m(covariant-by-declaration core::num i) → void
     return super.{self::A::m}(i);
 }
 class C extends self::B {
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.weak.expect b/pkg/front_end/testcases/general/issue47013d.dart.weak.expect
index 7039795..20bde3e 100644
--- a/pkg/front_end/testcases/general/issue47013d.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue47013d.dart.weak.expect
@@ -23,8 +23,8 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  forwarding-stub forwarding-semi-stub method m(covariant-by-declaration core::int i, covariant-by-declaration core::num n) → void
-    return super.{self::A::m}(i, n as core::int);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int, core::num) → void */ m(covariant-by-declaration core::num i, covariant-by-declaration core::int n) → void
+    return super.{self::A::m}(i, n);
 }
 static method main() → dynamic {
   self::B b = new self::B::•();
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47013d.dart.weak.outline.expect
index f310569..63ad8c8 100644
--- a/pkg/front_end/testcases/general/issue47013d.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/issue47013d.dart.weak.outline.expect
@@ -11,8 +11,8 @@
 class B extends self::A {
   synthetic constructor •() → self::B
     ;
-  forwarding-stub forwarding-semi-stub method m(covariant-by-declaration core::int i, covariant-by-declaration core::num n) → void
-    return super.{self::A::m}(i, n as core::int);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int, core::num) → void */ m(covariant-by-declaration core::num i, covariant-by-declaration core::int n) → void
+    return super.{self::A::m}(i, n);
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/general/issue47013d.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47013d.dart.weak.transformed.expect
index 7039795..20bde3e 100644
--- a/pkg/front_end/testcases/general/issue47013d.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue47013d.dart.weak.transformed.expect
@@ -23,8 +23,8 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  forwarding-stub forwarding-semi-stub method m(covariant-by-declaration core::int i, covariant-by-declaration core::num n) → void
-    return super.{self::A::m}(i, n as core::int);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int, core::num) → void */ m(covariant-by-declaration core::num i, covariant-by-declaration core::int n) → void
+    return super.{self::A::m}(i, n);
 }
 static method main() → dynamic {
   self::B b = new self::B::•();
diff --git a/pkg/front_end/testcases/general/override_setter_with_field.dart b/pkg/front_end/testcases/general/override_setter_with_field.dart
index df45e3a..28626d7 100644
--- a/pkg/front_end/testcases/general/override_setter_with_field.dart
+++ b/pkg/front_end/testcases/general/override_setter_with_field.dart
@@ -1,7 +1,9 @@
 // Copyright (c) 2019, 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.9
+
 abstract class A {
   void set x(Object y);
 }
diff --git a/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.expect b/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.expect
index 61d0c16..765d23f 100644
--- a/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.expect
+++ b/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/override_setter_with_field.dart:10:7: Error: The field 'B.x' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'A.x'.
+// pkg/front_end/testcases/general/override_setter_with_field.dart:12:7: Error: The field 'B.x' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'A.x'.
 //  - 'Object' is from 'dart:core'.
 //   int x;
 //       ^
-// pkg/front_end/testcases/general/override_setter_with_field.dart:6:12: Context: This is the overridden method ('x').
+// pkg/front_end/testcases/general/override_setter_with_field.dart:8:12: Context: This is the overridden method ('x').
 //   void set x(Object y);
 //            ^
 //
diff --git a/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.outline.expect b/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.outline.expect
index ff4e9c0..f7419b7 100644
--- a/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/override_setter_with_field.dart.weak.outline.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/override_setter_with_field.dart:10:7: Error: The field 'B.x' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'A.x'.
+// pkg/front_end/testcases/general/override_setter_with_field.dart:12:7: Error: The field 'B.x' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'A.x'.
 //  - 'Object' is from 'dart:core'.
 //   int x;
 //       ^
-// pkg/front_end/testcases/general/override_setter_with_field.dart:6:12: Context: This is the overridden method ('x').
+// pkg/front_end/testcases/general/override_setter_with_field.dart:8:12: Context: This is the overridden method ('x').
 //   void set x(Object y);
 //            ^
 //
diff --git a/pkg/front_end/testcases/general/super_semi_stub.dart b/pkg/front_end/testcases/general/super_semi_stub.dart
new file mode 100644
index 0000000..71a58db3
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_semi_stub.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Super {
+  void method(num a) {}
+  void set setter(num a) {}
+}
+
+class Class extends Super {
+  void method(covariant int a);
+  void set setter(covariant int a);
+}
+
+class Subclass extends Class {
+  void method(int a) {
+    void Function(num) sup1 = super.method; // ok
+    var sup2 = super.method;
+    void Function(num) cls1 = Class().method; // error
+    void Function(int) cls2 = Class().method; // ok
+    var cls3 = Class().method;
+  }
+
+  void set setter(int a) {
+    super.setter = 0; // ok
+    super.setter = 0.5; // ok
+    Class().setter = 0; // ok
+    Class().setter = 0.5; // error
+  }
+}
+
+test(Subclass sub) {
+  sub.method(0); // ok
+  sub.method(0.5); // error
+
+  Class cls = sub;
+  cls.method(0); // ok
+  cls.method(0.5); // error
+
+  Super sup = sub;
+  sup.method(0); // ok
+  sup.method(0.5); // ok
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/super_semi_stub.dart.textual_outline.expect b/pkg/front_end/testcases/general/super_semi_stub.dart.textual_outline.expect
new file mode 100644
index 0000000..f10e6b6
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_semi_stub.dart.textual_outline.expect
@@ -0,0 +1,17 @@
+class Super {
+  void method(num a) {}
+  void set setter(num a) {}
+}
+
+class Class extends Super {
+  void method(covariant int a);
+  void set setter(covariant int a);
+}
+
+class Subclass extends Class {
+  void method(int a) {}
+  void set setter(int a) {}
+}
+
+test(Subclass sub) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/super_semi_stub.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/super_semi_stub.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..332dc973
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_semi_stub.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Class extends Super {
+  void method(covariant int a);
+  void set setter(covariant int a);
+}
+
+class Subclass extends Class {
+  void method(int a) {}
+  void set setter(int a) {}
+}
+
+class Super {
+  void method(num a) {}
+  void set setter(num a) {}
+}
+
+main() {}
+test(Subclass sub) {}
diff --git a/pkg/front_end/testcases/general/super_semi_stub.dart.weak.expect b/pkg/front_end/testcases/general/super_semi_stub.dart.weak.expect
new file mode 100644
index 0000000..31c108e
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_semi_stub.dart.weak.expect
@@ -0,0 +1,76 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/super_semi_stub.dart:17:37: Error: A value of type 'void Function(int)' can't be assigned to a variable of type 'void Function(num)'.
+//     void Function(num) sup1 = super.method; // ok
+//                                     ^
+//
+// pkg/front_end/testcases/general/super_semi_stub.dart:19:39: Error: A value of type 'void Function(int)' can't be assigned to a variable of type 'void Function(num)'.
+//     void Function(num) cls1 = Class().method; // error
+//                                       ^
+//
+// pkg/front_end/testcases/general/super_semi_stub.dart:34:14: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+//   sub.method(0.5); // error
+//              ^
+//
+// pkg/front_end/testcases/general/super_semi_stub.dart:38:14: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+//   cls.method(0.5); // error
+//              ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+  method method(core::num a) → void {}
+  set setter(core::num a) → void {}
+}
+class Class extends self::Super {
+  synthetic constructor •() → self::Class
+    : super self::Super::•()
+    ;
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method}(a);
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter} = a;
+}
+class Subclass extends self::Class {
+  synthetic constructor •() → self::Subclass
+    : super self::Class::•()
+    ;
+  method method(covariant-by-declaration core::int a) → void {
+    (core::num) → void sup1 = invalid-expression "pkg/front_end/testcases/general/super_semi_stub.dart:17:37: Error: A value of type 'void Function(int)' can't be assigned to a variable of type 'void Function(num)'.
+    void Function(num) sup1 = super.method; // ok
+                                    ^" in super.{self::Class::method} as{TypeError,ForNonNullableByDefault} (core::num) → void;
+    (core::int) → void sup2 = super.{self::Class::method};
+    (core::num) → void cls1 = invalid-expression "pkg/front_end/testcases/general/super_semi_stub.dart:19:39: Error: A value of type 'void Function(int)' can't be assigned to a variable of type 'void Function(num)'.
+    void Function(num) cls1 = Class().method; // error
+                                      ^" in new self::Class::•().{self::Class::method}{(core::int) → void} as{TypeError,ForNonNullableByDefault} (core::num) → void;
+    (core::int) → void cls2 = new self::Class::•().{self::Class::method}{(core::int) → void};
+    (core::int) → void cls3 = new self::Class::•().{self::Class::method}{(core::int) → void};
+  }
+  set setter(covariant-by-declaration core::int a) → void {
+    super.{self::Class::setter} = 0;
+    super.{self::Class::setter} = 0.5;
+    new self::Class::•().{self::Class::setter} = 0;
+    new self::Class::•().{self::Class::setter} = 0.5;
+  }
+}
+static method test(self::Subclass sub) → dynamic {
+  sub.{self::Subclass::method}(0){(core::int) → void};
+  sub.{self::Subclass::method}(invalid-expression "pkg/front_end/testcases/general/super_semi_stub.dart:34:14: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+  sub.method(0.5); // error
+             ^" in 0.5 as{TypeError,ForNonNullableByDefault} core::int){(core::int) → void};
+  self::Class cls = sub;
+  cls.{self::Class::method}(0){(core::int) → void};
+  cls.{self::Class::method}(invalid-expression "pkg/front_end/testcases/general/super_semi_stub.dart:38:14: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+  cls.method(0.5); // error
+             ^" in 0.5 as{TypeError,ForNonNullableByDefault} core::int){(core::int) → void};
+  self::Super sup = sub;
+  sup.{self::Super::method}(0){(core::num) → void};
+  sup.{self::Super::method}(0.5){(core::num) → void};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/super_semi_stub.dart.weak.outline.expect b/pkg/front_end/testcases/general/super_semi_stub.dart.weak.outline.expect
new file mode 100644
index 0000000..dcca0c1
--- /dev/null
+++ b/pkg/front_end/testcases/general/super_semi_stub.dart.weak.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+  synthetic constructor •() → self::Super
+    ;
+  method method(core::num a) → void
+    ;
+  set setter(core::num a) → void
+    ;
+}
+class Class extends self::Super {
+  synthetic constructor •() → self::Class
+    ;
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method(covariant-by-declaration core::num a) → void
+    return super.{self::Super::method}(a);
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter(covariant-by-declaration core::num a) → void
+    return super.{self::Super::setter} = a;
+}
+class Subclass extends self::Class {
+  synthetic constructor •() → self::Subclass
+    ;
+  method method(covariant-by-declaration core::int a) → void
+    ;
+  set setter(covariant-by-declaration core::int a) → void
+    ;
+}
+static method test(self::Subclass sub) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/super_set_covariant.dart b/pkg/front_end/testcases/general/super_set_covariant.dart
index 88aaff1..a7d4d45 100644
--- a/pkg/front_end/testcases/general/super_set_covariant.dart
+++ b/pkg/front_end/testcases/general/super_set_covariant.dart
@@ -1,15 +1,16 @@
 // 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.9
+
 class SuperClass {
   void set setter(Object o) {}
 }
 
 abstract class Class extends SuperClass {
-  // TODO(johnniwinther): Should this introduce a concrete forwarding stub, and
-  // if so, should the target of the super set below be the forwarding super
-  // stub?
+  // This introduces a forwarding semi stub with the parameter type of
+  // the `SuperClass.setter` but with a signature type of `void Function(int)`.
   void set setter(covariant int o);
 }
 
diff --git a/pkg/front_end/testcases/general/super_set_covariant.dart.weak.expect b/pkg/front_end/testcases/general/super_set_covariant.dart.weak.expect
index 9153148..fede2f5 100644
--- a/pkg/front_end/testcases/general/super_set_covariant.dart.weak.expect
+++ b/pkg/front_end/testcases/general/super_set_covariant.dart.weak.expect
@@ -1,11 +1,4 @@
 library;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/super_set_covariant.dart:18:24: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-//     super.setter = '$o';
-//                        ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -29,7 +22,7 @@
   synthetic constructor •() → self::Class*
     : super self::SuperClass::•()
     ;
-  forwarding-stub forwarding-semi-stub set setter(covariant-by-declaration core::int* o) → void
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int*) →* void */ setter(covariant-by-declaration core::Object* o) → void
     return super.{self::SuperClass::setter} = o;
 }
 class SubClass extends self::Class {
@@ -37,9 +30,7 @@
     : super self::Class::•()
     ;
   set setter(covariant-by-declaration core::int* o) → void {
-    super.{self::Class::setter} = invalid-expression "pkg/front_end/testcases/general/super_set_covariant.dart:18:24: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-    super.setter = '\$o';
-                       ^" in "${o}" as{TypeError} core::int*;
+    super.{self::Class::setter} = "${o}";
   }
 }
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/general/super_set_covariant.dart.weak.outline.expect b/pkg/front_end/testcases/general/super_set_covariant.dart.weak.outline.expect
index 7500961..84045f4 100644
--- a/pkg/front_end/testcases/general/super_set_covariant.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/super_set_covariant.dart.weak.outline.expect
@@ -21,7 +21,7 @@
 abstract class Class extends self::SuperClass {
   synthetic constructor •() → self::Class*
     ;
-  forwarding-stub forwarding-semi-stub set setter(covariant-by-declaration core::int* o) → void
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int*) →* void */ setter(covariant-by-declaration core::Object* o) → void
     return super.{self::SuperClass::setter} = o;
 }
 class SubClass extends self::Class {
diff --git a/pkg/front_end/testcases/general/super_set_covariant.dart.weak.transformed.expect b/pkg/front_end/testcases/general/super_set_covariant.dart.weak.transformed.expect
index 9153148..fede2f5 100644
--- a/pkg/front_end/testcases/general/super_set_covariant.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/super_set_covariant.dart.weak.transformed.expect
@@ -1,11 +1,4 @@
 library;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/general/super_set_covariant.dart:18:24: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-//     super.setter = '$o';
-//                        ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -29,7 +22,7 @@
   synthetic constructor •() → self::Class*
     : super self::SuperClass::•()
     ;
-  forwarding-stub forwarding-semi-stub set setter(covariant-by-declaration core::int* o) → void
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int*) →* void */ setter(covariant-by-declaration core::Object* o) → void
     return super.{self::SuperClass::setter} = o;
 }
 class SubClass extends self::Class {
@@ -37,9 +30,7 @@
     : super self::Class::•()
     ;
   set setter(covariant-by-declaration core::int* o) → void {
-    super.{self::Class::setter} = invalid-expression "pkg/front_end/testcases/general/super_set_covariant.dart:18:24: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-    super.setter = '\$o';
-                       ^" in "${o}" as{TypeError} core::int*;
+    super.{self::Class::setter} = "${o}";
   }
 }
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
index 59d5c75..3595f53 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.expect
@@ -62,9 +62,9 @@
     : super core::Object::•()
     ;
   abstract get runtimeType() → self::CustomType;
-  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant-by-declaration self::CustomInvocation invocation) → core::String
+  forwarding-stub forwarding-semi-stub method /* signature-type: (self::CustomInvocation) → core::String */ noSuchMethod(covariant-by-declaration core::Invocation invocation) → core::String
     return super.{core::Object::noSuchMethod}(invocation);
-  forwarding-stub forwarding-semi-stub operator ==(covariant-by-declaration self::Class o) → core::bool
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (self::Class) → core::bool */ ==(covariant-by-declaration core::Object o) → core::bool
     return super.{core::Object::==}(o);
   abstract method toString({core::Object o = #C1}) → core::String;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.transformed.expect
index 59d5c75..3595f53 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.strong.transformed.expect
@@ -62,9 +62,9 @@
     : super core::Object::•()
     ;
   abstract get runtimeType() → self::CustomType;
-  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant-by-declaration self::CustomInvocation invocation) → core::String
+  forwarding-stub forwarding-semi-stub method /* signature-type: (self::CustomInvocation) → core::String */ noSuchMethod(covariant-by-declaration core::Invocation invocation) → core::String
     return super.{core::Object::noSuchMethod}(invocation);
-  forwarding-stub forwarding-semi-stub operator ==(covariant-by-declaration self::Class o) → core::bool
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (self::Class) → core::bool */ ==(covariant-by-declaration core::Object o) → core::bool
     return super.{core::Object::==}(o);
   abstract method toString({core::Object o = #C1}) → core::String;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
index 59d5c75..3595f53 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.expect
@@ -62,9 +62,9 @@
     : super core::Object::•()
     ;
   abstract get runtimeType() → self::CustomType;
-  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant-by-declaration self::CustomInvocation invocation) → core::String
+  forwarding-stub forwarding-semi-stub method /* signature-type: (self::CustomInvocation) → core::String */ noSuchMethod(covariant-by-declaration core::Invocation invocation) → core::String
     return super.{core::Object::noSuchMethod}(invocation);
-  forwarding-stub forwarding-semi-stub operator ==(covariant-by-declaration self::Class o) → core::bool
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (self::Class) → core::bool */ ==(covariant-by-declaration core::Object o) → core::bool
     return super.{core::Object::==}(o);
   abstract method toString({core::Object o = #C1}) → core::String;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.outline.expect
index b00ea1e..3b7cf09 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.outline.expect
@@ -16,9 +16,9 @@
   synthetic constructor •() → self::Class
     ;
   abstract get runtimeType() → self::CustomType;
-  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant-by-declaration self::CustomInvocation invocation) → core::String
+  forwarding-stub forwarding-semi-stub method /* signature-type: (self::CustomInvocation) → core::String */ noSuchMethod(covariant-by-declaration core::Invocation invocation) → core::String
     return super.{core::Object::noSuchMethod}(invocation);
-  forwarding-stub forwarding-semi-stub operator ==(covariant-by-declaration self::Class o) → core::bool
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (self::Class) → core::bool */ ==(covariant-by-declaration core::Object o) → core::bool
     return super.{core::Object::==}(o);
   abstract method toString({core::Object o}) → core::String;
 }
diff --git a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.transformed.expect
index 59d5c75..3595f53 100644
--- a/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_object_access.dart.weak.transformed.expect
@@ -62,9 +62,9 @@
     : super core::Object::•()
     ;
   abstract get runtimeType() → self::CustomType;
-  forwarding-stub forwarding-semi-stub method noSuchMethod(covariant-by-declaration self::CustomInvocation invocation) → core::String
+  forwarding-stub forwarding-semi-stub method /* signature-type: (self::CustomInvocation) → core::String */ noSuchMethod(covariant-by-declaration core::Invocation invocation) → core::String
     return super.{core::Object::noSuchMethod}(invocation);
-  forwarding-stub forwarding-semi-stub operator ==(covariant-by-declaration self::Class o) → core::bool
+  forwarding-stub forwarding-semi-stub operator /* signature-type: (self::Class) → core::bool */ ==(covariant-by-declaration core::Object o) → core::bool
     return super.{core::Object::==}(o);
   abstract method toString({core::Object o = #C1}) → core::String;
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect
index be2afd3..5a2032c 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.expect
@@ -129,11 +129,11 @@
     : super self::Super::•()
     ;
   abstract get field1() → core::int;
-  forwarding-stub forwarding-semi-stub set field1(covariant-by-declaration core::int #externalFieldValue) → void
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ field1(covariant-by-declaration core::num #externalFieldValue) → void
     return super.{self::Super::field1} = #externalFieldValue;
   abstract get field2() → core::String;
-  forwarding-stub forwarding-semi-stub set field2(covariant-by-declaration core::String #externalFieldValue) → void
-    return super.{self::Super::field2} = #externalFieldValue as core::num;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::String) → void */ field2(covariant-by-declaration core::num #externalFieldValue) → void
+    return super.{self::Super::field2} = #externalFieldValue;
   abstract get field3() → core::int;
   abstract set field3(core::int #externalFieldValue) → void;
   abstract get field4() → core::int;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect
index ca4fea2..699de2bc 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_field.dart.weak.outline.expect
@@ -126,11 +126,11 @@
   synthetic constructor •() → self::Class
     ;
   abstract get field1() → core::int;
-  forwarding-stub forwarding-semi-stub set field1(covariant-by-declaration core::int #externalFieldValue) → void
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ field1(covariant-by-declaration core::num #externalFieldValue) → void
     return super.{self::Super::field1} = #externalFieldValue;
   abstract get field2() → core::String;
-  forwarding-stub forwarding-semi-stub set field2(covariant-by-declaration core::String #externalFieldValue) → void
-    return super.{self::Super::field2} = #externalFieldValue as core::num;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::String) → void */ field2(covariant-by-declaration core::num #externalFieldValue) → void
+    return super.{self::Super::field2} = #externalFieldValue;
   abstract get field3() → core::int;
   abstract set field3(core::int #externalFieldValue) → void;
   abstract get field4() → core::int;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect
index e670210f..9e7d45a 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.expect
@@ -63,10 +63,10 @@
   synthetic constructor •() → self::Class
     : super self::Super::•()
     ;
-  forwarding-stub forwarding-semi-stub method method1(covariant-by-declaration core::int i) → void
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method1(covariant-by-declaration core::num i) → void
     return super.{self::Super::method1}(i);
-  forwarding-stub forwarding-semi-stub method method2(covariant-by-declaration core::String i) → void
-    return super.{self::Super::method2}(i as core::num);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::String) → void */ method2(covariant-by-declaration core::num i) → void
+    return super.{self::Super::method2}(i);
   abstract method method3(core::int i) → void;
   abstract method method4(covariant-by-declaration core::int i) → void;
   abstract method method5(covariant-by-declaration core::num n) → void;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect
index dc87ebf..47e31a3 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_method.dart.weak.outline.expect
@@ -69,10 +69,10 @@
 class Class extends self::Super implements self::Interface {
   synthetic constructor •() → self::Class
     ;
-  forwarding-stub forwarding-semi-stub method method1(covariant-by-declaration core::int i) → void
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::int) → void */ method1(covariant-by-declaration core::num i) → void
     return super.{self::Super::method1}(i);
-  forwarding-stub forwarding-semi-stub method method2(covariant-by-declaration core::String i) → void
-    return super.{self::Super::method2}(i as core::num);
+  forwarding-stub forwarding-semi-stub method /* signature-type: (core::String) → void */ method2(covariant-by-declaration core::num i) → void
+    return super.{self::Super::method2}(i);
   abstract method method3(core::int i) → void;
   abstract method method4(covariant-by-declaration core::int i) → void;
   abstract method method5(covariant-by-declaration core::num n) → void;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect
index f6fdb96..a51aa61 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.expect
@@ -63,10 +63,10 @@
   synthetic constructor •() → self::Class
     : super self::Super::•()
     ;
-  forwarding-stub forwarding-semi-stub set setter1(covariant-by-declaration core::int i) → void
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter1(covariant-by-declaration core::num i) → void
     return super.{self::Super::setter1} = i;
-  forwarding-stub forwarding-semi-stub set setter2(covariant-by-declaration core::String i) → void
-    return super.{self::Super::setter2} = i as core::num;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::String) → void */ setter2(covariant-by-declaration core::num i) → void
+    return super.{self::Super::setter2} = i;
   abstract set setter3(core::int i) → void;
   abstract set setter4(covariant-by-declaration core::int i) → void;
   abstract set setter5(covariant-by-declaration core::num n) → void;
diff --git a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect
index 1ac459f..77a5f5b 100644
--- a/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/hierarchy/forwarding_semi_stub_setter.dart.weak.outline.expect
@@ -69,10 +69,10 @@
 class Class extends self::Super implements self::Interface {
   synthetic constructor •() → self::Class
     ;
-  forwarding-stub forwarding-semi-stub set setter1(covariant-by-declaration core::int i) → void
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::int) → void */ setter1(covariant-by-declaration core::num i) → void
     return super.{self::Super::setter1} = i;
-  forwarding-stub forwarding-semi-stub set setter2(covariant-by-declaration core::String i) → void
-    return super.{self::Super::setter2} = i as core::num;
+  forwarding-stub forwarding-semi-stub set /* signature-type: (core::String) → void */ setter2(covariant-by-declaration core::num i) → void
+    return super.{self::Super::setter2} = i;
   abstract set setter3(core::int i) → void;
   abstract set setter4(covariant-by-declaration core::int i) → void;
   abstract set setter5(covariant-by-declaration core::num n) → void;
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart
new file mode 100644
index 0000000..bd46eb8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'test_lib.dart';
+
+main() {
+  test();
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.textual_outline.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.expect
new file mode 100644
index 0000000..b406d4f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.expect
@@ -0,0 +1,99 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+//   int j = sub.mixinMethod(null);
+//                           ^
+//
+// pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   int j = sub.mixinMethod(null);
+//               ^
+//
+// pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   sub.mixinField2 = sub.mixinField1;
+//                         ^
+//
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = invalid-expression "pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  int j = sub.mixinMethod(null);
+              ^" in sub.{opt::_SubClass&Class&Mixin::mixinMethod}(invalid-expression "pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+  int j = sub.mixinMethod(null);
+                          ^" in null as{TypeError,ForNonNullableByDefault} core::int){(core::int) →* core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = invalid-expression "pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  sub.mixinField2 = sub.mixinField1;
+                        ^" in sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int?} as{TypeError,ForNonNullableByDefault} core::int;
+}
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → self2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {}
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin extends self2::Class implements self2::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  field core::int? mixinField1 = null /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  field core::int mixinField2 = 0 /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super self2::Class::•()
+    ;
+  abstract member-signature get classField1() → core::int*; -> self2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> self2::Class::classField2
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {}
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> self2::Class::classMethod
+  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
+  abstract member-signature set classField1(core::int* value) → void; -> self2::Class::classField1
+  abstract member-signature set classField2(core::int* value) → void; -> self2::Class::classField2
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.outline.expect
new file mode 100644
index 0000000..bec1cf1
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.outline.expect
@@ -0,0 +1,70 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self3;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1;
+  field core::int classField2;
+  synthetic constructor •() → self3::Class
+    ;
+  method classMethod(core::int i) → core::int?
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1;
+  field core::int mixinField2;
+  method mixinMethod(core::int i) → core::int?
+    ;
+}
+
+library;
+import self as self4;
+import "opt_in_lib.dart" as self3;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin extends self3::Class implements self3::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  field core::int? mixinField1 /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  field core::int mixinField2 /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  synthetic constructor •() → self4::_SubClass&Class&Mixin*
+    : super self3::Class::•()
+    ;
+  abstract member-signature get classField1() → core::int*; -> self3::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> self3::Class::classField2
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int?
+    ;
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> self3::Class::classMethod
+  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
+  abstract member-signature set classField1(core::int* value) → void; -> self3::Class::classField1
+  abstract member-signature set classField2(core::int* value) → void; -> self3::Class::classField2
+}
+class SubClass extends self4::_SubClass&Class&Mixin {
+  synthetic constructor •() → self4::SubClass*
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.transformed.expect
new file mode 100644
index 0000000..f7a06b0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.dart.weak.transformed.expect
@@ -0,0 +1,99 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+//   int j = sub.mixinMethod(null);
+//                           ^
+//
+// pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   int j = sub.mixinMethod(null);
+//               ^
+//
+// pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+//   sub.mixinField2 = sub.mixinField1;
+//                         ^
+//
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = invalid-expression "pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:15: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  int j = sub.mixinMethod(null);
+              ^" in sub.{opt::_SubClass&Class&Mixin::mixinMethod}(invalid-expression "pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:10:27: Error: The value 'null' can't be assigned to the parameter type 'int' because 'int' is not nullable.
+  int j = sub.mixinMethod(null);
+                          ^" in null){(core::int) →* core::int?};
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = invalid-expression "pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart:12:25: Error: A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+  sub.mixinField2 = sub.mixinField1;
+                        ^" in sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int?};
+}
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → self2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {}
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin extends self2::Class implements self2::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  field core::int? mixinField1 = null /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  field core::int mixinField2 = 0 /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super self2::Class::•()
+    ;
+  abstract member-signature get classField1() → core::int*; -> self2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> self2::Class::classField2
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {}
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> self2::Class::classMethod
+  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
+  abstract member-signature set classField1(core::int* value) → void; -> self2::Class::classField1
+  abstract member-signature set classField2(core::int* value) → void; -> self2::Class::classField2
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart
new file mode 100644
index 0000000..bd46eb8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'test_lib.dart';
+
+main() {
+  test();
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.textual_outline.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..6f433ef
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+import 'test_lib.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.expect
new file mode 100644
index 0000000..5c88ecc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.expect
@@ -0,0 +1,85 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = sub.{opt::_SubClass&Class&Mixin::mixinMethod}(null){(core::int*) →* core::int*};
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int*};
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt2::Class with opt2::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt2::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt2::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt2::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt2::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+  mixin-super-stub method mixinMethod(core::int* i) → core::int*
+    return super.{opt2::Mixin::mixinMethod}(i);
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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 opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {}
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.outline.expect
new file mode 100644
index 0000000..898c9ca
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.outline.expect
@@ -0,0 +1,76 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic
+  ;
+
+library;
+import self as self3;
+import "opt_in_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin = opt::Class with opt::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self3::_SubClass&Class&Mixin*
+    : super opt::Class::•()
+    ;
+  mixin-super-stub get mixinField1() → core::int*
+    return super.{opt::Mixin::mixinField1};
+  mixin-super-stub set mixinField1(core::int* value) → void
+    return super.{opt::Mixin::mixinField1} = value;
+  mixin-super-stub get mixinField2() → core::int*
+    return super.{opt::Mixin::mixinField2};
+  mixin-super-stub set mixinField2(core::int* value) → void
+    return super.{opt::Mixin::mixinField2} = value;
+  abstract member-signature get classField1() → core::int*; -> opt::Class::classField1
+  abstract member-signature set classField1(core::int* value) → void; -> opt::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt::Class::classField2
+  abstract member-signature set classField2(core::int* value) → void; -> opt::Class::classField2
+  mixin-super-stub method mixinMethod(core::int* i) → core::int*
+    return super.{opt::Mixin::mixinMethod}(i);
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt::Class::classMethod
+  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 self3::_SubClass&Class&Mixin {
+  synthetic constructor •() → self3::SubClass*
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1;
+  field core::int classField2;
+  synthetic constructor •() → opt::Class
+    ;
+  method classMethod(core::int i) → core::int?
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1;
+  field core::int mixinField2;
+  method mixinMethod(core::int i) → core::int?
+    ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.transformed.expect
new file mode 100644
index 0000000..8b70b5c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/main.no_link.dart.weak.transformed.expect
@@ -0,0 +1,78 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "test_lib.dart" as tes;
+
+import "org-dartlang-testcase:///test_lib.dart";
+
+static method main() → dynamic {
+  tes::test();
+}
+
+library /*isNonNullableByDefault*/;
+import self as tes;
+import "opt_out_lib.dart" as opt;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_out_lib.dart";
+
+static method test() → dynamic {
+  opt::SubClass sub = new opt::SubClass::•();
+  core::int i = sub.{opt::_SubClass&Class&Mixin::classMethod}(null){(core::int*) →* core::int*};
+  core::int j = sub.{opt::_SubClass&Class&Mixin::mixinMethod}(null){(core::int*) →* core::int*};
+  sub.{opt::_SubClass&Class&Mixin::classField2} = sub.{opt::_SubClass&Class&Mixin::classField1}{core::int*};
+  sub.{opt::_SubClass&Class&Mixin::mixinField2} = sub.{opt::_SubClass&Class&Mixin::mixinField1}{core::int*};
+}
+
+library;
+import self as opt;
+import "opt_in_lib.dart" as opt2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///opt_in_lib.dart";
+
+abstract class _SubClass&Class&Mixin extends opt2::Class implements opt2::Mixin /*isAnonymousMixin,isEliminatedMixin*/  {
+  field core::int? mixinField1 = null /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  field core::int mixinField2 = 0 /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */;
+  synthetic constructor •() → opt::_SubClass&Class&Mixin*
+    : super opt2::Class::•()
+    ;
+  abstract member-signature get classField1() → core::int*; -> opt2::Class::classField1
+  abstract member-signature get classField2() → core::int*; -> opt2::Class::classField2
+  method /*isNonNullableByDefault, from org-dartlang-testcase:///opt_in_lib.dart */ mixinMethod(core::int i) → core::int? {}
+  abstract member-signature method classMethod(core::int* i) → core::int*; -> opt2::Class::classMethod
+  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
+  abstract member-signature set classField1(core::int* value) → void; -> opt2::Class::classField1
+  abstract member-signature set classField2(core::int* value) → void; -> opt2::Class::classField2
+}
+class SubClass extends opt::_SubClass&Class&Mixin {
+  synthetic constructor •() → opt::SubClass*
+    : super opt::_SubClass&Class&Mixin::•()
+    ;
+}
+
+library /*isNonNullableByDefault*/;
+import self as opt2;
+import "dart:core" as core;
+
+class Class extends core::Object {
+  field core::int? classField1 = null;
+  field core::int classField2 = 0;
+  synthetic constructor •() → opt2::Class
+    : super core::Object::•()
+    ;
+  method classMethod(core::int i) → core::int? {}
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+  field core::int? mixinField1 = null;
+  field core::int mixinField2 = 0;
+  method mixinMethod(core::int i) → core::int? {}
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/opt_in_lib.dart b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/opt_in_lib.dart
new file mode 100644
index 0000000..f85f5ca
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/opt_in_lib.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Class {
+  int? classField1;
+  int classField2 = 0;
+  int? classMethod(int i) {}
+}
+
+mixin Mixin {
+  int? mixinField1;
+  int mixinField2 = 0;
+  int? mixinMethod(int i) {}
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/opt_out_lib.dart b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/opt_out_lib.dart
new file mode 100644
index 0000000..e1f91ac
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/opt_out_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.9
+
+import 'opt_in_lib.dart';
+
+class SubClass extends Class with Mixin {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test.options b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test.options
new file mode 100644
index 0000000..c0f5433
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test.options
@@ -0,0 +1,2 @@
+opt_in_lib.dart
+opt_out_lib.dart
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart
new file mode 100644
index 0000000..1c2249c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/mixin_from_opt_in/test_lib.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'opt_out_lib.dart';
+
+test() {
+  SubClass sub = new SubClass();
+  int i = sub.classMethod(null);
+  int j = sub.mixinMethod(null);
+  sub.classField2 = sub.classField1;
+  sub.mixinField2 = sub.mixinField1;
+}
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 957e581..d03d29f 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -21,6 +21,7 @@
 general/crashes/crash_02/main: Crash
 general/crashes/crash_06/main: Crash
 general/getter_vs_setter_type: TypeCheckError
+general/implement_semi_stub: TypeCheckError
 general/infer_field_from_multiple: TypeCheckError
 general/invalid_operator: TypeCheckError
 general/invalid_operator_override: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index c9b65cc..f9b4d6d 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -76,6 +76,7 @@
 general/getter_vs_setter_type: TypeCheckError
 general/incomplete_field_formal_parameter: RuntimeError
 general/infer_field_from_multiple: TypeCheckError
+general/implement_semi_stub: TypeCheckError
 general/invalid_operator: TypeCheckError
 general/invalid_operator_override: TypeCheckError
 general/invocations: RuntimeError
@@ -104,6 +105,7 @@
 general/redirecting_factory: RuntimeError
 general/redirecting_factory_invocation_in_invalid: TypeCheckError
 general/spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
+general/super_semi_stub: TypeCheckError
 general/type_parameter_type_named_int: RuntimeError
 general/type_variable_as_super: RuntimeError
 general/unsound_promotion: TypeCheckError
@@ -150,6 +152,7 @@
 nnbd_mixed/issue41567: TypeCheckError
 nnbd_mixed/messages_with_types_opt_in: TypeCheckError
 nnbd_mixed/messages_with_types_opt_out: TypeCheckError
+nnbd_mixed/mixin_from_opt_in/main: RuntimeError
 rasta/abstract_constructor: RuntimeError
 rasta/bad_constructor_redirection: RuntimeError
 rasta/bad_continue: RuntimeError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index b9aca04..5b1bdb6 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -78,6 +78,7 @@
 general/error_recovery/yield_not_in_generator: RuntimeError
 general/expressions: RuntimeError
 general/getter_vs_setter_type: TypeCheckError
+general/implement_semi_stub: TypeCheckError
 general/incomplete_field_formal_parameter: RuntimeError
 general/infer_field_from_multiple: TypeCheckError
 general/invalid_operator: TypeCheckError
@@ -109,6 +110,7 @@
 general/redirecting_factory: RuntimeError
 general/redirecting_factory_invocation_in_invalid: TypeCheckError
 general/spread_collection: RuntimeError
+general/super_semi_stub: TypeCheckError
 general/type_parameter_type_named_int: RuntimeError # Expected
 general/type_variable_as_super: RuntimeError
 general/unsound_promotion: TypeCheckError
@@ -155,6 +157,7 @@
 nnbd_mixed/issue41567: TypeCheckError
 nnbd_mixed/messages_with_types_opt_in: TypeCheckError
 nnbd_mixed/messages_with_types_opt_out: TypeCheckError
+nnbd_mixed/mixin_from_opt_in/main: RuntimeError
 rasta/abstract_constructor: RuntimeError
 rasta/bad_constructor_redirection: RuntimeError
 rasta/bad_continue: RuntimeError
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 8c4fccf..e710da2 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -147,7 +147,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 73;
+  UInt32 formatVersion = 74;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -444,6 +444,7 @@
   Name name;
   List<Expression> annotations;
   MemberReference stubTarget; // May be NullReference.
+  Option<FunctionType> signatureType;
   FunctionNode function;
 }
 
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index ee30a76..19b2465 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -2031,9 +2031,82 @@
     node.parent = this;
   }
 
+  /// Returns the type of this member when accessed as a getter.
+  ///
+  /// For a field, this is the field type. For a getter, this is the return
+  /// type. For a method or constructor, this is the tear off type.
+  ///
+  /// For a setter, this is undefined. Currently, non-nullable `Never` is
+  /// returned.
+  // TODO(johnniwinther): Should we use `InvalidType` for the undefined cases?
   DartType get getterType;
+
+  /// Returns the type of this member when access as a getter on a super class.
+  ///
+  /// This is in most cases the same as for [getterType].
+  ///
+  /// An exception is for forwarding semi stubs:
+  ///
+  ///    class Super {
+  ///      void method(num a) {}
+  ///    }
+  ///    class Class extends Super {
+  ///      void method(covariant int a);
+  ///    }
+  ///    class Subclass extends Class {
+  ///      void method(int a) {
+  ///        super.method; // Type `void Function(num)`.
+  ///        Class().method; // Type `void Function(int)`.
+  ///      }
+  ///    }
+  ///
+  /// Here, `Class.method` is turned into a forwarding semi stub
+  ///
+  ///     void method(covariant num a) => super.method(a);
+  ///
+  /// with [signatureType] `void Function(int)`. When `Class.method` is used
+  /// as the target of a super get, it has getter type `void Function(num)` and
+  /// as the target of an instance get, it has getter type `void Function(int)`.
+  DartType get superGetterType => getterType;
+
+  /// Returns the type of this member when accessed as a setter.
+  ///
+  /// For an assignable field, this is the field type. For a setter this is the
+  /// parameter type.
+  ///
+  /// For other members, including unassignable fields, this is undefined.
+  /// Currently, non-nullable `Never` is returned.
+  // TODO(johnniwinther): Should we use `InvalidType` for the undefined cases?
   DartType get setterType;
 
+  /// Returns the type of this member when access as a setter on a super class.
+  ///
+  /// This is in most cases the same as for [setterType].
+  ///
+  /// An exception is for forwarding semi stubs:
+  ///
+  ///    class Super {
+  ///      void set setter(num a) {}
+  ///    }
+  ///    class Class extends Super {
+  ///      void set setter(covariant int a);
+  ///    }
+  ///    class Subclass extends Class {
+  ///      void set setter(int a) {
+  ///        super.setter = 0.5; // Valid.
+  ///        Class().setter = 0.5; // Invalid.
+  ///      }
+  ///    }
+  ///
+  /// Here, `Class.setter` is turned into a forwarding semi stub
+  ///
+  ///     void set setter(covariant num a) => super.setter = a;
+  ///
+  /// with [signatureType] `void Function(int)`. When `Class.setter` is used
+  /// as the target of a super set, it has setter type `num` and as the target
+  /// of an instance set, it has setter type `int`.
+  DartType get superSetterType => setterType;
+
   bool get containsSuperCalls {
     return transformerFlags & TransformerFlag.superCalls != 0;
   }
@@ -2436,6 +2509,7 @@
     }
   }
 
+  // TODO(johnniwinther): Provide the tear off type here.
   @override
   DartType get getterType => const NeverType.nonNullable();
 
@@ -2597,7 +2671,8 @@
   }
 
   @override
-  DartType get getterType => const NeverType.nonNullable();
+  DartType get getterType =>
+      function.computeFunctionType(enclosingLibrary.nonNullable);
 
   @override
   DartType get setterType => const NeverType.nonNullable();
@@ -2851,6 +2926,31 @@
   ProcedureStubKind stubKind;
   Reference? stubTargetReference;
 
+  /// The interface member signature type of this procedure.
+  ///
+  /// Normally this is derived from the parameter types and return type of
+  /// [function]. In rare cases, the interface member signature type is
+  /// different from the class member type, in which case the interface member
+  /// signature type is stored here.
+  ///
+  /// For instance
+  ///
+  ///   class Super {
+  ///     void method(num a) {}
+  ///   }
+  ///   class Class extends Super {
+  ///     void method(covariant int a);
+  ///   }
+  ///
+  /// Here the member `Class.method` is turned into a forwarding semi stub to
+  /// ensure that arguments passed to `Super.method` are checked as covariant.
+  /// Since `Super.method` allows `num` as argument, the inserted covariant
+  /// check must be against `num` and not `int`, and the parameter type of the
+  /// forwarding semi stub must be changed to `num`. Still, the interface of
+  /// `Class` requires that `Class.method` is `void Function(int)`, so for this,
+  /// it is stored explicitly as the [signatureType] on the procedure.
+  FunctionType? signatureType;
+
   Procedure(Name name, ProcedureKind kind, FunctionNode function,
       {bool isAbstract: false,
       bool isStatic: false,
@@ -3096,6 +3196,14 @@
   @override
   DartType get getterType {
     return isGetter
+        ? (signatureType?.returnType ?? function.returnType)
+        : (signatureType ??
+            function.computeFunctionType(enclosingLibrary.nonNullable));
+  }
+
+  @override
+  DartType get superGetterType {
+    return isGetter
         ? function.returnType
         : function.computeFunctionType(enclosingLibrary.nonNullable);
   }
@@ -3103,6 +3211,14 @@
   @override
   DartType get setterType {
     return isSetter
+        ? (signatureType?.positionalParameters[0] ??
+            function.positionalParameters[0].type)
+        : const NeverType.nonNullable();
+  }
+
+  @override
+  DartType get superSetterType {
+    return isSetter
         ? function.positionalParameters[0].type
         : const NeverType.nonNullable();
   }
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 12c33df..b1f1dcd 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1702,6 +1702,7 @@
         (kind == ProcedureKind.Factory && functionNodeSize <= 50) ||
             _disableLazyReading;
     Reference? stubTargetReference = readNullableMemberReference();
+    FunctionType? signatureType = readDartTypeOption() as FunctionType?;
     FunctionNode function = readFunctionNode(
         lazyLoadBody: !readFunctionNodeNow, outerEndOffset: endOffset);
     if (node == null) {
@@ -1724,6 +1725,7 @@
     node.setTransformerFlagsWithoutLazyLoading(transformerFlags);
     node.stubKind = stubKind;
     node.stubTargetReference = stubTargetReference;
+    node.signatureType = signatureType;
 
     assert((node.stubKind == ProcedureStubKind.ConcreteForwardingStub &&
             node.stubTargetReference != null) ||
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index a6d04bd..4cf39b7 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1314,6 +1314,7 @@
     writeName(node.name);
     writeAnnotationList(node.annotations);
     writeNullAllowedReference(node.stubTargetReference);
+    writeOptionalNode(node.signatureType);
     writeFunctionNode(node.function);
     leaveScope(memberScope: true);
 
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 8fb7add..859ed11 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -176,7 +176,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 73;
+  static const int BinaryFormatVersion = 74;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart
index 4a163b9..9e8ae3f 100644
--- a/pkg/kernel/lib/src/equivalence.dart
+++ b/pkg/kernel/lib/src/equivalence.dart
@@ -1795,6 +1795,9 @@
     if (!checkProcedure_stubTargetReference(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
+    if (!checkProcedure_signatureType(visitor, node, other)) {
+      result = visitor.resultOnInequivalence;
+    }
     if (!checkProcedure_fileEndOffset(visitor, node, other)) {
       result = visitor.resultOnInequivalence;
     }
@@ -5147,6 +5150,12 @@
         other.stubTargetReference, 'stubTargetReference');
   }
 
+  bool checkProcedure_signatureType(
+      EquivalenceVisitor visitor, Procedure node, Procedure other) {
+    return visitor.checkNodes(
+        node.signatureType, other.signatureType, 'signatureType');
+  }
+
   bool checkProcedure_fileEndOffset(
       EquivalenceVisitor visitor, Procedure node, Procedure other) {
     return checkMember_fileEndOffset(visitor, node, other);
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index faf9eaa..42babc4 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1208,6 +1208,11 @@
     if (features.isNotEmpty) {
       writeWord("/*${features.join(',')}*/");
     }
+    if (node.signatureType != null) {
+      writeWord('/* signature-type:');
+      writeType(node.signatureType!);
+      writeWord('*/');
+    }
     switch (node.stubKind) {
       case ProcedureStubKind.Regular:
       case ProcedureStubKind.AbstractForwardingStub:
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 9b8b502..e575a00 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -760,7 +760,7 @@
       checkUnresolvedInvocation(currentThisType!, node);
       return handleDynamicCall(currentThisType!, node.arguments);
     } else {
-      return handleCall(node.arguments, target.getterType,
+      return handleCall(node.arguments, target.superGetterType,
           receiver: getSuperReceiverType(target));
     }
   }
@@ -773,7 +773,7 @@
       return const DynamicType();
     } else {
       Substitution receiver = getSuperReceiverType(target);
-      return receiver.substituteType(target.getterType);
+      return receiver.substituteType(target.superGetterType);
     }
   }
 
@@ -784,7 +784,7 @@
     if (target != null) {
       Substitution receiver = getSuperReceiverType(target);
       checkAssignable(node.value, value,
-          receiver.substituteType(target.setterType, contravariant: true));
+          receiver.substituteType(target.superSetterType, contravariant: true));
     } else {
       checkUnresolvedInvocation(currentThisType!, node);
     }
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index c987ed3..9ca03f4 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -2128,6 +2128,7 @@
   Class& cls = Class::Handle(Z);
   Array& functions = Array::Handle(Z);
   Function& function = Function::Handle(Z);
+  Function& target = Function::Handle(Z);
   Code& code = Code::Handle(Z);
   Object& owner = Object::Handle(Z);
   GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z);
@@ -2135,6 +2136,24 @@
   auto& ref = Object::Handle(Z);
 
   auto trim_function = [&](const Function& function) {
+    if (function.IsDynamicInvocationForwarder()) {
+      // For dynamic invocation forwarders sever strong connection between the
+      // forwarder and the target function if we are not going to retain
+      // target function anyway. The only use of the forwarding target outside
+      // of compilation pipeline is in Function::script() and that should not
+      // be used when we are dropping functions (cause we are not going to
+      // emit symbolic stack traces anyway).
+      // Note that we still need Function::script() to work during snapshot
+      // generation to generate DWARF, that's why we are using WSR and not
+      // simply setting forwarding target to null.
+      target = function.ForwardingTarget();
+      if (!functions_to_retain_.ContainsKey(target)) {
+        ref =
+            WeakSerializationReference::New(target, Function::null_function());
+        function.set_data(ref);
+      }
+    }
+
     sig = function.signature();
     // In the AOT runtime, most calls are direct or through the dispatch table,
     // not resolved via dynamic lookup. Thus, we only need to retain the
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index db4e074..378ea73 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1166,6 +1166,10 @@
       }
       if (++next_read_ == field) return;
       FALL_THROUGH;
+    case kSignatureType:
+      helper_->SkipOptionalDartType();  // read signature type.
+      if (++next_read_ == field) return;
+      FALL_THROUGH;
     case kFunction:
       helper_->SkipFunctionNode();  // read function node.
       if (++next_read_ == field) return;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index c854d07..cfe75b0 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -532,6 +532,7 @@
     kName,
     kAnnotations,
     kStubTarget,
+    kSignatureType,
     kFunction,
     kEnd,
   };
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 65b7bd5..46d20ec 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,8 +20,8 @@
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
 
 // Both version numbers are inclusive.
-static const uint32_t kMinSupportedKernelFormatVersion = 73;
-static const uint32_t kMaxSupportedKernelFormatVersion = 73;
+static const uint32_t kMinSupportedKernelFormatVersion = 74;
+static const uint32_t kMaxSupportedKernelFormatVersion = 74;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 1fa6c99..48c4c22 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3897,10 +3897,7 @@
   forwarder.set_optimized_call_site_count(0);
 
   forwarder.InheritKernelOffsetFrom(*this);
-
-  const Array& checks = Array::Handle(zone, Array::New(1));
-  checks.SetAt(0, *this);
-  forwarder.SetForwardingChecks(checks);
+  forwarder.SetForwardingTarget(*this);
 
   return forwarder.ptr();
 }
@@ -7623,16 +7620,12 @@
 
 FunctionPtr Function::ForwardingTarget() const {
   ASSERT(kind() == UntaggedFunction::kDynamicInvocationForwarder);
-  Array& checks = Array::Handle();
-  checks ^= data();
-  return Function::RawCast(checks.At(0));
+  return Function::RawCast(WeakSerializationReference::Unwrap(data()));
 }
 
-void Function::SetForwardingChecks(const Array& checks) const {
+void Function::SetForwardingTarget(const Function& target) const {
   ASSERT(kind() == UntaggedFunction::kDynamicInvocationForwarder);
-  ASSERT(checks.Length() >= 1);
-  ASSERT(Object::Handle(checks.At(0)).IsFunction());
-  set_data(checks);
+  set_data(target);
 }
 
 // This field is heavily overloaded:
@@ -7654,8 +7647,9 @@
 //   regular function:        Function for implicit closure function
 //   constructor, factory:    Function for implicit closure function
 //   ffi trampoline function: FfiTrampolineData  (Dart->C)
-//   dyn inv forwarder:       Array[0] = Function target
-//                            Array[1] = TypeArguments default type args
+//   dyn inv forwarder:       Forwarding target, a WSR pointing to it or null
+//                            (null can only occur if forwarding target was
+//                            dropped)
 void Function::set_data(const Object& value) const {
   untag()->set_data<std::memory_order_release>(value.ptr());
 }
@@ -9652,15 +9646,15 @@
 ScriptPtr Function::script() const {
   // NOTE(turnidge): If you update this function, you probably want to
   // update Class::PatchFieldsAndFunctions() at the same time.
-  const Object& data = Object::Handle(this->data());
   if (IsDynamicInvocationForwarder()) {
-    const auto& forwarding_target = Function::Handle(ForwardingTarget());
-    return forwarding_target.script();
+    const Function& target = Function::Handle(ForwardingTarget());
+    return target.IsNull() ? Script::null() : target.script();
   }
   if (IsImplicitGetterOrSetter()) {
     const auto& field = Field::Handle(accessor_field());
     return field.Script();
   }
+  Object& data = Object::Handle(this->data());
   if (data.IsArray()) {
     Object& script = Object::Handle(Array::Cast(data).At(0));
     if (script.IsScript()) {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 7959652..2ef9d1d 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2953,7 +2953,7 @@
   intptr_t ComputeClosureHash() const;
 
   FunctionPtr ForwardingTarget() const;
-  void SetForwardingChecks(const Array& checks) const;
+  void SetForwardingTarget(const Function& target) const;
 
   UntaggedFunction::Kind kind() const {
     return untag()->kind_tag_.Read<KindBits>();
diff --git a/tools/VERSION b/tools/VERSION
index 31e67dc..1328561 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 214
+PRERELEASE 215
 PRERELEASE_PATCH 0
\ No newline at end of file