[cfe] Add test for forwarding stub targets

The added test show that we generate a super call to the wrong target
in some forwarding stubs. The target should have been the mixed in
member but is instead the super member that it overrides.

Change-Id: If7536628370ba69405cbedef969e727a5d220058
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170684
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/testcases/general/mixin_covariant2.dart b/pkg/front_end/testcases/general/mixin_covariant2.dart
new file mode 100644
index 0000000..8454114
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant2.dart
@@ -0,0 +1,53 @@
+// 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.
+
+class Superclass {
+  String method1(num argument1, num argument2) => "Superclass";
+  String method2(num argument1, num argument2) => "Superclass";
+  String method3(num argument1, covariant int argument2) => "Superclass";
+  String method4(num argument1, covariant num argument2) => "Superclass";
+}
+
+class Mixin {
+  String method1(num argument1, num argument2) => "Mixin";
+  String method2(covariant int argument1, num argument2) => "Mixin";
+  String method3(num argument1, num argument2) => "Mixin";
+  String method4(covariant int argument1, int argument2) => "Mixin";
+}
+
+class Class extends Superclass with Mixin {}
+
+main() {
+  Class c = new Class();
+  expect("Mixin", c.method1(0, 1));
+  expect("Mixin", c.method2(0, 1));
+  expect("Mixin", c.method3(0, 1));
+  expect("Mixin", c.method4(0, 1));
+
+  Superclass s = c;
+  expect("Mixin", s.method1(0.5, 1.5));
+  throws(() => s.method2(0.5, 1.5));
+  expect("Mixin", s.method3(0.5, 1));
+  throws(() => s.method4(0.5, 1));
+  expect("Mixin", s.method4(1, 0.5));
+
+  Mixin m = c;
+  expect("Mixin", m.method1(0, 1));
+  expect("Mixin", m.method2(0, 1));
+  expect("Mixin", m.method3(0, 1));
+  expect("Mixin", m.method4(0, 1));
+}
+
+void expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+void throws(void Function() f) {
+  try {
+    f();
+  } catch (_) {
+    return;
+  }
+  throw 'Expected exception';
+}
diff --git a/pkg/front_end/testcases/general/mixin_covariant2.dart.outline.expect b/pkg/front_end/testcases/general/mixin_covariant2.dart.outline.expect
new file mode 100644
index 0000000..8a608cb
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant2.dart.outline.expect
@@ -0,0 +1,68 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  synthetic constructor •() → self::Superclass*
+    ;
+  method method1(core::num* argument1, core::num* argument2) → core::String*
+    ;
+  method method2(core::num* argument1, core::num* argument2) → core::String*
+    ;
+  method method3(core::num* argument1, covariant core::int* argument2) → core::String*
+    ;
+  method method4(core::num* argument1, covariant core::num* argument2) → core::String*
+    ;
+  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 Mixin extends core::Object {
+  synthetic constructor •() → self::Mixin*
+    ;
+  method method1(core::num* argument1, core::num* argument2) → core::String*
+    ;
+  method method2(covariant core::int* argument1, core::num* argument2) → core::String*
+    ;
+  method method3(core::num* argument1, core::num* argument2) → core::String*
+    ;
+  method method4(covariant core::int* argument1, core::int* argument2) → core::String*
+    ;
+  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 class _Class&Superclass&Mixin = self::Superclass with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Superclass&Mixin*
+    : super self::Superclass::•()
+    ;
+  abstract forwarding-stub method method2(covariant core::num* argument1, core::num* argument2) → core::String*;
+  forwarding-stub method method3(core::num* argument1, covariant core::num* argument2) → core::String*
+    return super.{self::Superclass::method3}(argument1, argument2);
+  forwarding-stub method method4(covariant core::num* argument1, covariant core::num* argument2) → core::String*
+    return super.{self::Superclass::method4}(argument1, argument2);
+}
+class Class extends self::_Class&Superclass&Mixin {
+  synthetic constructor •() → self::Class*
+    ;
+}
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → void
+  ;
+static method throws(() →* void f) → void
+  ;
diff --git a/pkg/front_end/testcases/general/mixin_covariant2.dart.strong.expect b/pkg/front_end/testcases/general/mixin_covariant2.dart.strong.expect
new file mode 100644
index 0000000..62e8537
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant2.dart.strong.expect
@@ -0,0 +1,96 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  synthetic constructor •() → self::Superclass*
+    : super core::Object::•()
+    ;
+  method method1(core::num* argument1, core::num* argument2) → core::String*
+    return "Superclass";
+  method method2(core::num* argument1, core::num* argument2) → core::String*
+    return "Superclass";
+  method method3(core::num* argument1, covariant core::int* argument2) → core::String*
+    return "Superclass";
+  method method4(core::num* argument1, covariant core::num* argument2) → core::String*
+    return "Superclass";
+  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 Mixin extends core::Object {
+  synthetic constructor •() → self::Mixin*
+    : super core::Object::•()
+    ;
+  method method1(core::num* argument1, core::num* argument2) → core::String*
+    return "Mixin";
+  method method2(covariant core::int* argument1, core::num* argument2) → core::String*
+    return "Mixin";
+  method method3(core::num* argument1, core::num* argument2) → core::String*
+    return "Mixin";
+  method method4(covariant core::int* argument1, core::int* argument2) → core::String*
+    return "Mixin";
+  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 class _Class&Superclass&Mixin = self::Superclass with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Superclass&Mixin*
+    : super self::Superclass::•()
+    ;
+  abstract forwarding-stub method method2(covariant core::num* argument1, core::num* argument2) → core::String*;
+  forwarding-stub method method3(core::num* argument1, covariant core::num* argument2) → core::String*
+    return super.{self::Superclass::method3}(argument1, argument2);
+  forwarding-stub method method4(covariant core::num* argument1, covariant core::num* argument2) → core::String*
+    return super.{self::Superclass::method4}(argument1, argument2);
+}
+class Class extends self::_Class&Superclass&Mixin {
+  synthetic constructor •() → self::Class*
+    : super self::_Class&Superclass&Mixin::•()
+    ;
+}
+static method main() → dynamic {
+  self::Class* c = new self::Class::•();
+  self::expect("Mixin", c.{self::Mixin::method1}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method2}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method3}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method4}(0, 1));
+  self::Superclass* s = c;
+  self::expect("Mixin", s.{self::Superclass::method1}(0.5, 1.5));
+  self::throws(() → core::String* => s.{self::Superclass::method2}(0.5, 1.5));
+  self::expect("Mixin", s.{self::Superclass::method3}(0.5, 1));
+  self::throws(() → core::String* => s.{self::Superclass::method4}(0.5, 1));
+  self::expect("Mixin", s.{self::Superclass::method4}(1, 0.5));
+  self::Mixin* m = c;
+  self::expect("Mixin", m.{self::Mixin::method1}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method2}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method3}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method4}(0, 1));
+}
+static method expect(dynamic expected, dynamic actual) → void {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() →* void f) → void {
+  try {
+    f.call();
+  }
+  on dynamic catch(final dynamic _) {
+    return;
+  }
+  throw "Expected exception";
+}
diff --git a/pkg/front_end/testcases/general/mixin_covariant2.dart.textual_outline.expect b/pkg/front_end/testcases/general/mixin_covariant2.dart.textual_outline.expect
new file mode 100644
index 0000000..6f22d96
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant2.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Superclass {
+  String method1(num argument1, num argument2) => "Superclass";
+  String method2(num argument1, num argument2) => "Superclass";
+  String method3(num argument1, covariant int argument2) => "Superclass";
+  String method4(num argument1, covariant num argument2) => "Superclass";
+}
+
+class Mixin {
+  String method1(num argument1, num argument2) => "Mixin";
+  String method2(covariant int argument1, num argument2) => "Mixin";
+  String method3(num argument1, num argument2) => "Mixin";
+  String method4(covariant int argument1, int argument2) => "Mixin";
+}
+
+class Class extends Superclass with Mixin {}
+
+main() {}
+void expect(expected, actual) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/general/mixin_covariant2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/mixin_covariant2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9f3d0b4
--- /dev/null
+++ b/pkg/front_end/testcases/general/mixin_covariant2.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+class Class extends Superclass with Mixin {}
+
+class Mixin {
+  String method1(num argument1, num argument2) => "Mixin";
+  String method2(covariant int argument1, num argument2) => "Mixin";
+  String method3(num argument1, num argument2) => "Mixin";
+  String method4(covariant int argument1, int argument2) => "Mixin";
+}
+
+class Superclass {
+  String method1(num argument1, num argument2) => "Superclass";
+  String method2(num argument1, num argument2) => "Superclass";
+  String method3(num argument1, covariant int argument2) => "Superclass";
+  String method4(num argument1, covariant num argument2) => "Superclass";
+}
+
+main() {}
+void expect(expected, actual) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart b/pkg/front_end/testcases/none/mixin_covariant.dart
new file mode 100644
index 0000000..8454114
--- /dev/null
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart
@@ -0,0 +1,53 @@
+// 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.
+
+class Superclass {
+  String method1(num argument1, num argument2) => "Superclass";
+  String method2(num argument1, num argument2) => "Superclass";
+  String method3(num argument1, covariant int argument2) => "Superclass";
+  String method4(num argument1, covariant num argument2) => "Superclass";
+}
+
+class Mixin {
+  String method1(num argument1, num argument2) => "Mixin";
+  String method2(covariant int argument1, num argument2) => "Mixin";
+  String method3(num argument1, num argument2) => "Mixin";
+  String method4(covariant int argument1, int argument2) => "Mixin";
+}
+
+class Class extends Superclass with Mixin {}
+
+main() {
+  Class c = new Class();
+  expect("Mixin", c.method1(0, 1));
+  expect("Mixin", c.method2(0, 1));
+  expect("Mixin", c.method3(0, 1));
+  expect("Mixin", c.method4(0, 1));
+
+  Superclass s = c;
+  expect("Mixin", s.method1(0.5, 1.5));
+  throws(() => s.method2(0.5, 1.5));
+  expect("Mixin", s.method3(0.5, 1));
+  throws(() => s.method4(0.5, 1));
+  expect("Mixin", s.method4(1, 0.5));
+
+  Mixin m = c;
+  expect("Mixin", m.method1(0, 1));
+  expect("Mixin", m.method2(0, 1));
+  expect("Mixin", m.method3(0, 1));
+  expect("Mixin", m.method4(0, 1));
+}
+
+void expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+void throws(void Function() f) {
+  try {
+    f();
+  } catch (_) {
+    return;
+  }
+  throw 'Expected exception';
+}
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.outline.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.outline.expect
new file mode 100644
index 0000000..a0757dd
--- /dev/null
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.outline.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  synthetic constructor •() → self::Superclass
+    ;
+  method method1(core::num argument1, core::num argument2) → core::String
+    ;
+  method method2(core::num argument1, core::num argument2) → core::String
+    ;
+  method method3(core::num argument1, covariant core::int argument2) → core::String
+    ;
+  method method4(core::num argument1, covariant core::num argument2) → core::String
+    ;
+}
+class Mixin extends core::Object {
+  synthetic constructor •() → self::Mixin
+    ;
+  method method1(core::num argument1, core::num argument2) → core::String
+    ;
+  method method2(covariant core::int argument1, core::num argument2) → core::String
+    ;
+  method method3(core::num argument1, core::num argument2) → core::String
+    ;
+  method method4(covariant core::int argument1, core::int argument2) → core::String
+    ;
+}
+abstract class _Class&Superclass&Mixin = self::Superclass with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Superclass&Mixin
+    : super self::Superclass::•()
+    ;
+  abstract forwarding-stub method method2(covariant core::num argument1, core::num argument2) → core::String;
+  forwarding-stub method method3(core::num argument1, covariant core::num argument2) → core::String
+    return super.{self::Superclass::method3}(argument1, argument2);
+  forwarding-stub method method4(covariant core::num argument1, covariant core::num argument2) → core::String
+    return super.{self::Superclass::method4}(argument1, argument2);
+}
+class Class extends self::_Class&Superclass&Mixin {
+  synthetic constructor •() → self::Class
+    ;
+}
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → void
+  ;
+static method throws(() → void f) → void
+  ;
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.strong.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.strong.expect
new file mode 100644
index 0000000..412bbf0
--- /dev/null
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.strong.expect
@@ -0,0 +1,76 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  synthetic constructor •() → self::Superclass
+    : super core::Object::•()
+    ;
+  method method1(core::num argument1, core::num argument2) → core::String
+    return "Superclass";
+  method method2(core::num argument1, core::num argument2) → core::String
+    return "Superclass";
+  method method3(core::num argument1, covariant core::int argument2) → core::String
+    return "Superclass";
+  method method4(core::num argument1, covariant core::num argument2) → core::String
+    return "Superclass";
+}
+class Mixin extends core::Object {
+  synthetic constructor •() → self::Mixin
+    : super core::Object::•()
+    ;
+  method method1(core::num argument1, core::num argument2) → core::String
+    return "Mixin";
+  method method2(covariant core::int argument1, core::num argument2) → core::String
+    return "Mixin";
+  method method3(core::num argument1, core::num argument2) → core::String
+    return "Mixin";
+  method method4(covariant core::int argument1, core::int argument2) → core::String
+    return "Mixin";
+}
+abstract class _Class&Superclass&Mixin = self::Superclass with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Superclass&Mixin
+    : super self::Superclass::•()
+    ;
+  abstract forwarding-stub method method2(covariant core::num argument1, core::num argument2) → core::String;
+  forwarding-stub method method3(core::num argument1, covariant core::num argument2) → core::String
+    return super.{self::Superclass::method3}(argument1, argument2);
+  forwarding-stub method method4(covariant core::num argument1, covariant core::num argument2) → core::String
+    return super.{self::Superclass::method4}(argument1, argument2);
+}
+class Class extends self::_Class&Superclass&Mixin {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Superclass&Mixin::•()
+    ;
+}
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  self::expect("Mixin", c.{self::Mixin::method1}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method2}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method3}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method4}(0, 1));
+  self::Superclass s = c;
+  self::expect("Mixin", s.{self::Superclass::method1}(0.5, 1.5));
+  self::throws(() → void => s.{self::Superclass::method2}(0.5, 1.5));
+  self::expect("Mixin", s.{self::Superclass::method3}(0.5, 1));
+  self::throws(() → void => s.{self::Superclass::method4}(0.5, 1));
+  self::expect("Mixin", s.{self::Superclass::method4}(1, 0.5));
+  self::Mixin m = c;
+  self::expect("Mixin", m.{self::Mixin::method1}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method2}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method3}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method4}(0, 1));
+}
+static method expect(dynamic expected, dynamic actual) → void {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → void f) → void {
+  try {
+    f.call();
+  }
+  on core::Object catch(final core::Object _) {
+    return;
+  }
+  throw "Expected exception";
+}
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.textual_outline.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.textual_outline.expect
new file mode 100644
index 0000000..6f22d96
--- /dev/null
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.textual_outline.expect
@@ -0,0 +1,19 @@
+class Superclass {
+  String method1(num argument1, num argument2) => "Superclass";
+  String method2(num argument1, num argument2) => "Superclass";
+  String method3(num argument1, covariant int argument2) => "Superclass";
+  String method4(num argument1, covariant num argument2) => "Superclass";
+}
+
+class Mixin {
+  String method1(num argument1, num argument2) => "Mixin";
+  String method2(covariant int argument1, num argument2) => "Mixin";
+  String method3(num argument1, num argument2) => "Mixin";
+  String method4(covariant int argument1, int argument2) => "Mixin";
+}
+
+class Class extends Superclass with Mixin {}
+
+main() {}
+void expect(expected, actual) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9f3d0b4
--- /dev/null
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+class Class extends Superclass with Mixin {}
+
+class Mixin {
+  String method1(num argument1, num argument2) => "Mixin";
+  String method2(covariant int argument1, num argument2) => "Mixin";
+  String method3(num argument1, num argument2) => "Mixin";
+  String method4(covariant int argument1, int argument2) => "Mixin";
+}
+
+class Superclass {
+  String method1(num argument1, num argument2) => "Superclass";
+  String method2(num argument1, num argument2) => "Superclass";
+  String method3(num argument1, covariant int argument2) => "Superclass";
+  String method4(num argument1, covariant num argument2) => "Superclass";
+}
+
+main() {}
+void expect(expected, actual) {}
+void throws(void Function() f) {}
diff --git a/pkg/front_end/testcases/none/mixin_covariant.dart.weak.expect b/pkg/front_end/testcases/none/mixin_covariant.dart.weak.expect
new file mode 100644
index 0000000..412bbf0
--- /dev/null
+++ b/pkg/front_end/testcases/none/mixin_covariant.dart.weak.expect
@@ -0,0 +1,76 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Superclass extends core::Object {
+  synthetic constructor •() → self::Superclass
+    : super core::Object::•()
+    ;
+  method method1(core::num argument1, core::num argument2) → core::String
+    return "Superclass";
+  method method2(core::num argument1, core::num argument2) → core::String
+    return "Superclass";
+  method method3(core::num argument1, covariant core::int argument2) → core::String
+    return "Superclass";
+  method method4(core::num argument1, covariant core::num argument2) → core::String
+    return "Superclass";
+}
+class Mixin extends core::Object {
+  synthetic constructor •() → self::Mixin
+    : super core::Object::•()
+    ;
+  method method1(core::num argument1, core::num argument2) → core::String
+    return "Mixin";
+  method method2(covariant core::int argument1, core::num argument2) → core::String
+    return "Mixin";
+  method method3(core::num argument1, core::num argument2) → core::String
+    return "Mixin";
+  method method4(covariant core::int argument1, core::int argument2) → core::String
+    return "Mixin";
+}
+abstract class _Class&Superclass&Mixin = self::Superclass with self::Mixin /*isAnonymousMixin*/  {
+  synthetic constructor •() → self::_Class&Superclass&Mixin
+    : super self::Superclass::•()
+    ;
+  abstract forwarding-stub method method2(covariant core::num argument1, core::num argument2) → core::String;
+  forwarding-stub method method3(core::num argument1, covariant core::num argument2) → core::String
+    return super.{self::Superclass::method3}(argument1, argument2);
+  forwarding-stub method method4(covariant core::num argument1, covariant core::num argument2) → core::String
+    return super.{self::Superclass::method4}(argument1, argument2);
+}
+class Class extends self::_Class&Superclass&Mixin {
+  synthetic constructor •() → self::Class
+    : super self::_Class&Superclass&Mixin::•()
+    ;
+}
+static method main() → dynamic {
+  self::Class c = new self::Class::•();
+  self::expect("Mixin", c.{self::Mixin::method1}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method2}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method3}(0, 1));
+  self::expect("Mixin", c.{self::_Class&Superclass&Mixin::method4}(0, 1));
+  self::Superclass s = c;
+  self::expect("Mixin", s.{self::Superclass::method1}(0.5, 1.5));
+  self::throws(() → void => s.{self::Superclass::method2}(0.5, 1.5));
+  self::expect("Mixin", s.{self::Superclass::method3}(0.5, 1));
+  self::throws(() → void => s.{self::Superclass::method4}(0.5, 1));
+  self::expect("Mixin", s.{self::Superclass::method4}(1, 0.5));
+  self::Mixin m = c;
+  self::expect("Mixin", m.{self::Mixin::method1}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method2}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method3}(0, 1));
+  self::expect("Mixin", m.{self::Mixin::method4}(0, 1));
+}
+static method expect(dynamic expected, dynamic actual) → void {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → void f) → void {
+  try {
+    f.call();
+  }
+  on core::Object catch(final core::Object _) {
+    return;
+  }
+  throw "Expected exception";
+}
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 532869a..8ddb02d 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -23,6 +23,7 @@
 general/issue41210a: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
 general/mixin_application_override: TypeCheckError
+general/mixin_covariant2: TypeCheckError
 general/override_check_accessor_after_inference: TypeCheckError
 general/override_check_accessor_basic: TypeCheckError
 general/override_check_accessor_with_covariant_modifier: TypeCheckError
@@ -47,6 +48,7 @@
 nnbd/covariant_late_field: TypeCheckError
 nnbd/getter_vs_setter_type: TypeCheckError
 nnbd/issue42603: TypeCheckError
+none/mixin_covariant: TypeCheckError
 rasta/native_is_illegal: Pass # Issue 29763
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
 runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 674fd31..8df4cda 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -78,6 +78,7 @@
 general/mixin_application_override: ExpectationFileMismatch # Too many errors.
 general/mixin_application_override: TypeCheckError
 general/mixin_constructors_with_default_values: RuntimeError # Expected
+general/mixin_covariant2: TypeCheckError
 general/operator_method_not_found: RuntimeError # Expected
 general/optional: TypeCheckError
 general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
@@ -174,6 +175,7 @@
 nnbd/nullable_object_access: TypeCheckError
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
+none/mixin_covariant: TypeCheckError
 rasta/abstract_constructor: RuntimeError
 rasta/bad_constructor_redirection: RuntimeError
 rasta/bad_continue: RuntimeError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 3605015..20825b3 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -81,6 +81,7 @@
 general/micro: RuntimeError
 general/mixin_application_override: TypeCheckError
 general/mixin_constructors_with_default_values: RuntimeError
+general/mixin_covariant2: TypeCheckError
 general/operator_method_not_found: RuntimeError
 general/optional: TypeCheckError
 general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
@@ -176,6 +177,7 @@
 nnbd/nullable_object_access: TypeCheckError
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
+none/mixin_covariant: TypeCheckError
 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 21b2c44..23bbcca 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -72,6 +72,7 @@
 nnbd_mixed/messages_with_types_opt_out: TypeCheckError
 nnbd_mixed/super_access/main: Crash # Issue 43864
 nnbd_mixed/super_access/main.no_link: Crash # Issue 43864
+none/mixin_covariant: TypeCheckError
 value_class/simple: RuntimeError # Expected
 value_class/value_extends_non_value: RuntimeError # Expected
 value_class/value_implements_non_value: RuntimeError # Expected