[dart2js] Enable kernel verification
This enables kernel verification of components loaded from source when
asserts are enabled.
Change-Id: Icf5d42e2c978428138733403f9af35824e97821c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/299641
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart b/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart
index 5473990..a6f8d6c 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/export_creator.dart
@@ -192,7 +192,8 @@
}
var jsExporter = VariableDeclaration('#jsExporter',
- initializer: AsExpression(getLiteral(proto), returnType),
+ initializer: AsExpression(getLiteral(proto), returnType)
+ ..fileOffset = node.fileOffset,
type: returnType,
isSynthesized: true)
..fileOffset = node.fileOffset
diff --git a/pkg/compiler/lib/src/phase/load_kernel.dart b/pkg/compiler/lib/src/phase/load_kernel.dart
index b446993..af36d04 100644
--- a/pkg/compiler/lib/src/phase/load_kernel.dart
+++ b/pkg/compiler/lib/src/phase/load_kernel.dart
@@ -15,6 +15,7 @@
import 'package:kernel/target/targets.dart' hide DiagnosticReporter;
import 'package:_js_interop_checks/src/transformations/static_interop_class_eraser.dart';
+import 'package:kernel/verifier.dart';
import '../../compiler_api.dart' as api;
import '../commandline_options.dart';
@@ -302,6 +303,18 @@
verbosity: verbosity);
ir.Component? component = await fe.compile(initializedCompilerState, verbose,
fileSystem, onDiagnostic, sources, isModularCompile);
+
+ assert(() {
+ if (component != null) {
+ // TODO(johnniwinther): Support verification of erroneous programs.
+ if (!reporter.hasReportedError) {
+ verifyComponent(
+ target, VerificationStage.afterModularTransformations, component);
+ }
+ }
+ return true;
+ }());
+
_doTransformsOnKernelLoad(component);
// We have to compute canonical names on the component here to avoid missing
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 18f74ec..4cd2eae 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -4554,7 +4554,7 @@
node,
new StaticInvocation(
target, unevaluatedArguments(positional, named, arguments.types),
- isConst: true));
+ isConst: node.isConst));
}
if (target.kind == ProcedureKind.Factory) {
if (target.isConst) {
@@ -4581,7 +4581,7 @@
node,
new StaticInvocation(target,
unevaluatedArguments(positional, named, arguments.types),
- isConst: true));
+ isConst: node.isConst));
}
} else if (target.isExternal) {
return createEvaluationErrorConstant(
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 2162752..93d38a7 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -264,6 +264,10 @@
if (target is Procedure && target.isRedirectingFactory) {
target = builder.readTarget!;
}
+ Class targetClass = target.enclosingClass!;
+ if (target is Constructor && targetClass.isAbstract) {
+ continue;
+ }
Name targetName =
new Name(constructorName, declaration.libraryBuilder.library);
Reference? tearOffReference;
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart
new file mode 100644
index 0000000..e7b8cf9
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2023, 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.
+
+abstract class Class {
+ Class();
+ factory Class.redirect() = ClassImpl;
+}
+
+class ClassImpl implements Class {}
+
+typedef F<T> = Class;
+
+test() {
+ Class.new; // Error
+ Class.redirect; // Ok
+ F.new; // Error
+ F.redirect; // Ok
+}
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.strong.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.strong.expect
new file mode 100644
index 0000000..1c37d16
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.strong.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+ static method _#redirect#tearOff() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::ClassImpl
+ return new self::ClassImpl::•();
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::_#redirect#tearOff();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = static-tearoff self::Class::_#redirect#tearOff
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..1c37d16
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+ static method _#redirect#tearOff() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::ClassImpl
+ return new self::ClassImpl::•();
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::_#redirect#tearOff();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = static-tearoff self::Class::_#redirect#tearOff
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..b8a9891
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class Class {
+ Class();
+ factory Class.redirect() = ClassImpl;
+}
+
+class ClassImpl implements Class {}
+
+typedef F<T> = Class;
+test() {}
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b97f8ca
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class Class {
+ Class();
+ factory Class.redirect() = ClassImpl;
+}
+
+class ClassImpl implements Class {}
+
+test() {}
+typedef F<T> = Class;
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.expect
new file mode 100644
index 0000000..1c37d16
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+ static method _#redirect#tearOff() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::ClassImpl
+ return new self::ClassImpl::•();
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::_#redirect#tearOff();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = static-tearoff self::Class::_#redirect#tearOff
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.modular.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.modular.expect
new file mode 100644
index 0000000..1c37d16
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.modular.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+ static method _#redirect#tearOff() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::ClassImpl
+ return new self::ClassImpl::•();
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::_#redirect#tearOff();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = static-tearoff self::Class::_#redirect#tearOff
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..ed3a00a
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.outline.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[self::Class::redirect]/*isLegacy*/;
+ constructor •() → self::Class
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+ static method _#redirect#tearOff() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ ;
+ static method _#new#tearOff() → self::ClassImpl
+ return new self::ClassImpl::•();
+}
+static method test() → dynamic
+ ;
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::_#redirect#tearOff();
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///abstract_tear_off.dart:5:16 -> ConstructorTearOffConstant(Class.redirect)
+Extra constant evaluation: evaluated: 6, effectively constant: 1
diff --git a/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..1c37d16
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/abstract_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+ static method _#redirect#tearOff() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::ClassImpl
+ return new self::ClassImpl::•();
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/dart2js/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::_#redirect#tearOff();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = static-tearoff self::Class::_#redirect#tearOff
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart b/pkg/front_end/testcases/general/abstract_tear_off.dart
new file mode 100644
index 0000000..e7b8cf9
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2023, 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.
+
+abstract class Class {
+ Class();
+ factory Class.redirect() = ClassImpl;
+}
+
+class ClassImpl implements Class {}
+
+typedef F<T> = Class;
+
+test() {
+ Class.new; // Error
+ Class.redirect; // Ok
+ F.new; // Error
+ F.redirect; // Ok
+}
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.strong.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.strong.expect
new file mode 100644
index 0000000..6d6be75cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.strong.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::redirect();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = redirecting-factory-tearoff self::Class::redirect
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..6d6be75cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::redirect();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = redirecting-factory-tearoff self::Class::redirect
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..b8a9891
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+abstract class Class {
+ Class();
+ factory Class.redirect() = ClassImpl;
+}
+
+class ClassImpl implements Class {}
+
+typedef F<T> = Class;
+test() {}
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..b97f8ca
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,9 @@
+abstract class Class {
+ Class();
+ factory Class.redirect() = ClassImpl;
+}
+
+class ClassImpl implements Class {}
+
+test() {}
+typedef F<T> = Class;
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.expect
new file mode 100644
index 0000000..6d6be75cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::redirect();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = redirecting-factory-tearoff self::Class::redirect
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.modular.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.modular.expect
new file mode 100644
index 0000000..6d6be75cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.modular.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::redirect();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = redirecting-factory-tearoff self::Class::redirect
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..d0e48de
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[self::Class::redirect]/*isLegacy*/;
+ constructor •() → self::Class
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ ;
+}
+static method test() → dynamic
+ ;
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::redirect();
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///abstract_tear_off.dart:5:16 -> ConstructorTearOffConstant(Class.redirect)
+Extra constant evaluation: evaluated: 4, effectively constant: 1
diff --git a/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..6d6be75cf
--- /dev/null
+++ b/pkg/front_end/testcases/general/abstract_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+// Class.new; // Error
+// ^^^
+//
+// pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+// F.new; // Error
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated T extends core::Object? = dynamic> = self::Class;
+abstract class Class extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[#C1]/*isLegacy*/;
+ constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ static factory redirect() → self::Class
+ return new self::ClassImpl::•();
+}
+class ClassImpl extends core::Object implements self::Class {
+ synthetic constructor •() → self::ClassImpl
+ : super core::Object::•()
+ ;
+}
+static method test() → dynamic {
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:15:9: Error: Constructors on abstract classes can't be torn off.
+ Class.new; // Error
+ ^^^";
+ #C2;
+ invalid-expression "pkg/front_end/testcases/general/abstract_tear_off.dart:17:5: Error: Constructors on abstract classes can't be torn off.
+ F.new; // Error
+ ^^^";
+ #C3;
+}
+static method _#F#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::Class
+ return self::Class::redirect();
+
+constants {
+ #C1 = constructor-tearoff self::Class::redirect
+ #C2 = redirecting-factory-tearoff self::Class::redirect
+ #C3 = static-tearoff self::_#F#redirect#tearOff
+}
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.expect
index 4d039bc..d12b0e4 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.expect
@@ -126,7 +126,7 @@
#C22 = static-tearoff var::id2
#C23 = eval #C22<core::int>
#C24 = eval #C20 ?{(core::int) → core::int} #C21 : #C23
- #C25 = eval const core::identical(#C3, #C24)
+ #C25 = eval core::identical(#C3, #C24)
#C26 = static-tearoff core::identical
}
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.transformed.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.transformed.expect
index 44b37ee..28dd954 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.strong.transformed.expect
@@ -126,7 +126,7 @@
#C22 = static-tearoff var::id2
#C23 = eval #C22<core::int>
#C24 = eval #C20 ?{(core::int) → core::int} #C21 : #C23
- #C25 = eval const core::identical(#C3, #C24)
+ #C25 = eval core::identical(#C3, #C24)
#C26 = static-tearoff core::identical
}
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.expect
index 243b858..e9db17c 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.expect
@@ -126,7 +126,7 @@
#C22 = static-tearoff var::id2
#C23 = eval #C22<core::int>
#C24 = eval #C20 ?{(core::int) → core::int} #C21 : #C23
- #C25 = eval const core::identical(#C3, #C24)
+ #C25 = eval core::identical(#C3, #C24)
#C26 = static-tearoff core::identical
}
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.modular.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.modular.expect
index 243b858..e9db17c 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.modular.expect
@@ -126,7 +126,7 @@
#C22 = static-tearoff var::id2
#C23 = eval #C22<core::int>
#C24 = eval #C20 ?{(core::int) → core::int} #C21 : #C23
- #C25 = eval const core::identical(#C3, #C24)
+ #C25 = eval core::identical(#C3, #C24)
#C26 = static-tearoff core::identical
}
diff --git a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.transformed.expect
index fd2b782..e40d672 100644
--- a/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/constants/with_unevaluated_agnostic/various_2.dart.weak.transformed.expect
@@ -126,7 +126,7 @@
#C22 = static-tearoff var::id2
#C23 = eval #C22<core::int>
#C24 = eval #C20 ?{(core::int) → core::int} #C21 : #C23
- #C25 = eval const core::identical(#C3, #C24)
+ #C25 = eval core::identical(#C3, #C24)
#C26 = static-tearoff core::identical
}