[cfe] Create const constructor in mixin application with only static fields
Closes #40982
Change-Id: I2fc426735ece176cc81a9da33e33fd3ad14e756a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171592
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 4cd7a7e..56a9123 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -749,7 +749,15 @@
Class cls = classBuilder.cls;
Constructor constructor = memberBuilder.member;
- bool isConst = constructor.isConst && mixin.fields.isEmpty;
+ bool isConst = constructor.isConst;
+ if (isConst && mixin.fields.isNotEmpty) {
+ for (Field field in mixin.fields) {
+ if (!field.isStatic) {
+ isConst = false;
+ break;
+ }
+ }
+ }
List<VariableDeclaration> positionalParameters = <VariableDeclaration>[];
List<VariableDeclaration> namedParameters = <VariableDeclaration>[];
List<Expression> positional = <Expression>[];
diff --git a/pkg/front_end/testcases/general/issue40982.dart b/pkg/front_end/testcases/general/issue40982.dart
new file mode 100644
index 0000000..ed06fc3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart
@@ -0,0 +1,37 @@
+// 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 A {
+ const A();
+}
+
+mixin B {
+ static const int value = 1;
+}
+
+class C1 extends A with B {
+ const C1();
+}
+
+class C2 = A with B;
+
+class C3 extends C2 {
+ const C3();
+}
+
+mixin D {
+ int value = 1;
+}
+
+class E1 extends A with D {
+ const E1();
+}
+
+class E2 = A with D;
+
+class E3 extends E2 {
+ const E3();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.outline.expect b/pkg/front_end/testcases/general/issue40982.dart.outline.expect
new file mode 100644
index 0000000..642ab52
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.outline.expect
@@ -0,0 +1,98 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40982.dart:28:9: Error: A constant constructor can't call a non-constant super constructor.
+// const E1();
+// ^
+//
+// pkg/front_end/testcases/general/issue40982.dart:34:9: Error: A constant constructor can't call a non-constant super constructor.
+// const E3();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::A*
+ : super core::Object::•()
+ ;
+ 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 B extends core::Object /*isMixinDeclaration*/ {
+ static const field core::int* value = 1;
+ 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 _C1&A&B = self::A with self::B /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •() → self::_C1&A&B*
+ : super self::A::•()
+ ;
+}
+class C1 extends self::_C1&A&B /*hasConstConstructor*/ {
+ const constructor •() → self::C1*
+ : super self::_C1&A&B::•()
+ ;
+}
+class C2 = self::A with self::B /*hasConstConstructor*/ {
+ const synthetic constructor •() → self::C2*
+ : super self::A::•()
+ ;
+}
+class C3 extends self::C2 /*hasConstConstructor*/ {
+ const constructor •() → self::C3*
+ : super self::C2::•()
+ ;
+}
+abstract class D extends core::Object /*isMixinDeclaration*/ {
+ field core::int* value;
+ 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 _E1&A&D = self::A with self::D /*isAnonymousMixin*/ {
+ synthetic constructor •() → self::_E1&A&D*
+ : super self::A::•()
+ ;
+}
+class E1 extends self::_E1&A&D /*hasConstConstructor*/ {
+ const constructor •() → self::E1*
+ : super self::_E1&A&D::•()
+ ;
+}
+class E2 = self::A with self::D {
+ synthetic constructor •() → self::E2*
+ : super self::A::•()
+ ;
+}
+class E3 extends self::E2 /*hasConstConstructor*/ {
+ const constructor •() → self::E3*
+ : super self::E2::•()
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/issue40982.dart.strong.expect b/pkg/front_end/testcases/general/issue40982.dart.strong.expect
new file mode 100644
index 0000000..d5bdf49
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.strong.expect
@@ -0,0 +1,101 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40982.dart:28:9: Error: A constant constructor can't call a non-constant super constructor.
+// const E1();
+// ^
+//
+// pkg/front_end/testcases/general/issue40982.dart:34:9: Error: A constant constructor can't call a non-constant super constructor.
+// const E3();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::A*
+ : super core::Object::•()
+ ;
+ 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 B extends core::Object /*isMixinDeclaration*/ {
+ static const field core::int* value = #C1;
+ 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 _C1&A&B = self::A with self::B /*isAnonymousMixin,hasConstConstructor*/ {
+ const synthetic constructor •() → self::_C1&A&B*
+ : super self::A::•()
+ ;
+}
+class C1 extends self::_C1&A&B /*hasConstConstructor*/ {
+ const constructor •() → self::C1*
+ : super self::_C1&A&B::•()
+ ;
+}
+class C2 = self::A with self::B /*hasConstConstructor*/ {
+ const synthetic constructor •() → self::C2*
+ : super self::A::•()
+ ;
+}
+class C3 extends self::C2 /*hasConstConstructor*/ {
+ const constructor •() → self::C3*
+ : super self::C2::•()
+ ;
+}
+abstract class D extends core::Object /*isMixinDeclaration*/ {
+ field core::int* value = 1;
+ 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 _E1&A&D = self::A with self::D /*isAnonymousMixin*/ {
+ synthetic constructor •() → self::_E1&A&D*
+ : super self::A::•()
+ ;
+}
+class E1 extends self::_E1&A&D /*hasConstConstructor*/ {
+ const constructor •() → self::E1*
+ : super self::_E1&A&D::•()
+ ;
+}
+class E2 = self::A with self::D {
+ synthetic constructor •() → self::E2*
+ : super self::A::•()
+ ;
+}
+class E3 extends self::E2 /*hasConstConstructor*/ {
+ const constructor •() → self::E3*
+ : super self::E2::•()
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40982.dart.strong.transformed.expect
new file mode 100644
index 0000000..a903a15
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.strong.transformed.expect
@@ -0,0 +1,145 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40982.dart:28:9: Error: A constant constructor can't call a non-constant super constructor.
+// const E1();
+// ^
+//
+// pkg/front_end/testcases/general/issue40982.dart:34:9: Error: A constant constructor can't call a non-constant super constructor.
+// const E3();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object /*hasConstConstructor*/ {
+ const constructor •() → self::A*
+ : super core::Object::•()
+ ;
+ 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 B extends core::Object /*isMixinDeclaration*/ {
+ static const field core::int* value = #C1;
+ 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 _C1&A&B extends self::A implements self::B /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
+ static const field core::int* value = #C1;
+ const synthetic constructor •() → self::_C1&A&B*
+ : super self::A::•()
+ ;
+ 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 C1 extends self::_C1&A&B /*hasConstConstructor*/ {
+ const constructor •() → self::C1*
+ : super self::_C1&A&B::•()
+ ;
+}
+class C2 extends self::A implements self::B /*isEliminatedMixin,hasConstConstructor*/ {
+ static const field core::int* value = #C1;
+ const synthetic constructor •() → self::C2*
+ : super self::A::•()
+ ;
+ 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 C3 extends self::C2 /*hasConstConstructor*/ {
+ const constructor •() → self::C3*
+ : super self::C2::•()
+ ;
+}
+abstract class D extends core::Object /*isMixinDeclaration*/ {
+ field core::int* value = 1;
+ 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 _E1&A&D extends self::A implements self::D /*isAnonymousMixin,isEliminatedMixin*/ {
+ field core::int* value = 1;
+ synthetic constructor •() → self::_E1&A&D*
+ : super self::A::•()
+ ;
+ 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 E1 extends self::_E1&A&D /*hasConstConstructor*/ {
+ const constructor •() → self::E1*
+ : super self::_E1&A&D::•()
+ ;
+}
+class E2 extends self::A implements self::D /*isEliminatedMixin*/ {
+ field core::int* value = 1;
+ synthetic constructor •() → self::E2*
+ : super self::A::•()
+ ;
+ 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 E3 extends self::E2 /*hasConstConstructor*/ {
+ const constructor •() → self::E3*
+ : super self::E2::•()
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue40982.dart.textual_outline.expect
new file mode 100644
index 0000000..d0c04bf
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.textual_outline.expect
@@ -0,0 +1,33 @@
+class A {
+ const A();
+}
+
+mixin B {
+ static const int value = 1;
+}
+
+class C1 extends A with B {
+ const C1();
+}
+
+class C2 = A with B;
+
+class C3 extends C2 {
+ const C3();
+}
+
+mixin D {
+ int value = 1;
+}
+
+class E1 extends A with D {
+ const E1();
+}
+
+class E2 = A with D;
+
+class E3 extends E2 {
+ const E3();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue40982.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue40982.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..eeaccee
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40982.dart.textual_outline_modelled.expect
@@ -0,0 +1,31 @@
+class A {
+ const A();
+}
+
+class C1 extends A with B {
+ const C1();
+}
+
+class C2 = A with B;
+
+class C3 extends C2 {
+ const C3();
+}
+
+class E1 extends A with D {
+ const E1();
+}
+
+class E2 = A with D;
+
+class E3 extends E2 {
+ const E3();
+}
+
+main() {}
+mixin B {
+ static const int value = 1;
+}
+mixin D {
+ int value = 1;
+}