[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