Version 2.18.0-77.0.dev
Merge commit '7ab89309fb413b5e17c635b11ae375e61a13a411' into 'dev'
diff --git a/DEPS b/DEPS
index bca6358..51d7633 100644
--- a/DEPS
+++ b/DEPS
@@ -79,7 +79,7 @@
"args_rev": "3b3f55766af13d895d2020ec001a28e8dc147f91",
"async_rev": "f3ed5f690e2ec9dbe1bfc5184705575b4f6480e5",
"bazel_worker_rev": "ceeba0982d4ff40d32371c9d35f3d2dc1868de20",
- "benchmark_harness_rev": "6a99d14719ef3f251041a9fcbe0589f312499696",
+ "benchmark_harness_rev": "0530da692a5d689f4b5450a7c8d1a8abe3e2d555",
"boolean_selector_rev": "437e7f06c7e416bed91e16ae1df453555897e945",
"boringssl_gen_rev": "ced85ef0a00bbca77ce5a91261a5f2ae61b1e62f",
"boringssl_rev": "87f316d7748268eb56f2dc147bd593254ae93198",
diff --git a/benchmarks/AsyncLiveVars/dart/AsyncLiveVars.dart b/benchmarks/AsyncLiveVars/dart/AsyncLiveVars.dart
index 7969da6..2cd702cc 100644
--- a/benchmarks/AsyncLiveVars/dart/AsyncLiveVars.dart
+++ b/benchmarks/AsyncLiveVars/dart/AsyncLiveVars.dart
@@ -7,7 +7,7 @@
import 'dart:async';
-import 'async_benchmark_base.dart' show AsyncBenchmarkBase;
+import 'package:benchmark_harness/benchmark_harness.dart';
class MockClass {
static final String str = "${int.parse('42')}";
diff --git a/benchmarks/AsyncLiveVars/dart/async_benchmark_base.dart b/benchmarks/AsyncLiveVars/dart/async_benchmark_base.dart
deleted file mode 100644
index 9a415b9..0000000
--- a/benchmarks/AsyncLiveVars/dart/async_benchmark_base.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:benchmark_harness/benchmark_harness.dart'
- show PrintEmitter, ScoreEmitter;
-
-// Similar to BenchmarkBase from package:benchmark_harness.
-class AsyncBenchmarkBase {
- final String name;
- final ScoreEmitter emitter;
-
- // Empty constructor.
- const AsyncBenchmarkBase(this.name, {this.emitter = const PrintEmitter()});
-
- // The benchmark code.
- // This function is not used, if both [warmup] and [exercise] are overwritten.
- Future<void> run() async {}
-
- // Runs a short version of the benchmark. By default invokes [run] once.
- Future<void> warmup() async {
- await run();
- }
-
- // Exercises the benchmark. By default invokes [run] 10 times.
- Future<void> exercise() async {
- for (var i = 0; i < 10; i++) {
- await run();
- }
- }
-
- // Not measured setup code executed prior to the benchmark runs.
- Future<void> setup() async {}
-
- // Not measures teardown code executed after the benchark runs.
- Future<void> teardown() async {}
-
- // Measures the score for this benchmark by executing it repeatedly until
- // time minimum has been reached.
- static Future<double> measureFor(Function f, int minimumMillis) async {
- final int minimumMicros = minimumMillis * 1000;
- int iter = 0;
- final watch = Stopwatch();
- watch.start();
- int elapsed = 0;
- while (elapsed < minimumMicros) {
- await f();
- elapsed = watch.elapsedMicroseconds;
- iter++;
- }
- return elapsed / iter;
- }
-
- // Measures the score for the benchmark and returns it.
- Future<double> measure() async {
- await setup();
- // Warmup for at least 100ms. Discard result.
- await measureFor(warmup, 100);
- // Run the benchmark for at least 2000ms.
- final result = await measureFor(exercise, 2000);
- await teardown();
- return result;
- }
-
- Future<void> report() async {
- emitter.emit(name, await measure());
- }
-}
diff --git a/benchmarks/AsyncLiveVars/dart2/AsyncLiveVars.dart b/benchmarks/AsyncLiveVars/dart2/AsyncLiveVars.dart
index 9176274..20ac726 100644
--- a/benchmarks/AsyncLiveVars/dart2/AsyncLiveVars.dart
+++ b/benchmarks/AsyncLiveVars/dart2/AsyncLiveVars.dart
@@ -9,7 +9,7 @@
import 'dart:async';
-import 'async_benchmark_base.dart' show AsyncBenchmarkBase;
+import 'package:benchmark_harness/benchmark_harness.dart';
class MockClass {
static final String str = "${int.parse('42')}";
diff --git a/benchmarks/AsyncLiveVars/dart2/async_benchmark_base.dart b/benchmarks/AsyncLiveVars/dart2/async_benchmark_base.dart
deleted file mode 100644
index 9a415b9..0000000
--- a/benchmarks/AsyncLiveVars/dart2/async_benchmark_base.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:benchmark_harness/benchmark_harness.dart'
- show PrintEmitter, ScoreEmitter;
-
-// Similar to BenchmarkBase from package:benchmark_harness.
-class AsyncBenchmarkBase {
- final String name;
- final ScoreEmitter emitter;
-
- // Empty constructor.
- const AsyncBenchmarkBase(this.name, {this.emitter = const PrintEmitter()});
-
- // The benchmark code.
- // This function is not used, if both [warmup] and [exercise] are overwritten.
- Future<void> run() async {}
-
- // Runs a short version of the benchmark. By default invokes [run] once.
- Future<void> warmup() async {
- await run();
- }
-
- // Exercises the benchmark. By default invokes [run] 10 times.
- Future<void> exercise() async {
- for (var i = 0; i < 10; i++) {
- await run();
- }
- }
-
- // Not measured setup code executed prior to the benchmark runs.
- Future<void> setup() async {}
-
- // Not measures teardown code executed after the benchark runs.
- Future<void> teardown() async {}
-
- // Measures the score for this benchmark by executing it repeatedly until
- // time minimum has been reached.
- static Future<double> measureFor(Function f, int minimumMillis) async {
- final int minimumMicros = minimumMillis * 1000;
- int iter = 0;
- final watch = Stopwatch();
- watch.start();
- int elapsed = 0;
- while (elapsed < minimumMicros) {
- await f();
- elapsed = watch.elapsedMicroseconds;
- iter++;
- }
- return elapsed / iter;
- }
-
- // Measures the score for the benchmark and returns it.
- Future<double> measure() async {
- await setup();
- // Warmup for at least 100ms. Discard result.
- await measureFor(warmup, 100);
- // Run the benchmark for at least 2000ms.
- final result = await measureFor(exercise, 2000);
- await teardown();
- return result;
- }
-
- Future<void> report() async {
- emitter.emit(name, await measure());
- }
-}
diff --git a/benchmarks/Isolate/dart/Isolate.dart b/benchmarks/Isolate/dart/Isolate.dart
index b703340..55e5377 100644
--- a/benchmarks/Isolate/dart/Isolate.dart
+++ b/benchmarks/Isolate/dart/Isolate.dart
@@ -6,8 +6,7 @@
import 'dart:isolate';
import 'dart:typed_data';
-import 'package:benchmark_harness/benchmark_harness.dart'
- show PrintEmitter, ScoreEmitter;
+import 'package:benchmark_harness/benchmark_harness.dart';
class SendReceiveBytes extends AsyncBenchmarkBase {
SendReceiveBytes(String name,
@@ -35,46 +34,6 @@
late SendReceiveHelper helper;
}
-// Identical to BenchmarkBase from package:benchmark_harness but async.
-abstract class AsyncBenchmarkBase {
- final String name;
- final ScoreEmitter emitter;
-
- Future<void> run();
- Future<void> setup();
- Future<void> teardown();
-
- const AsyncBenchmarkBase(this.name, {this.emitter = const PrintEmitter()});
-
- // Returns the number of microseconds per call.
- Future<double> measureFor(int minimumMillis) async {
- final minimumMicros = minimumMillis * 1000;
- int iter = 0;
- final watch = Stopwatch();
- watch.start();
- int elapsed = 0;
- while (elapsed < minimumMicros) {
- await run();
- elapsed = watch.elapsedMicroseconds;
- iter++;
- }
- return elapsed / iter;
- }
-
- // Measures the score for the benchmark and returns it.
- Future<double> measure() async {
- await setup();
- await measureFor(500); // warm-up
- final result = await measureFor(4000); // actual measurement
- await teardown();
- return result;
- }
-
- Future<void> report() async {
- emitter.emit(name, await measure());
- }
-}
-
class StartMessage {
final SendPort sendPort;
final bool useTransferable;
diff --git a/benchmarks/Isolate/dart2/Isolate.dart b/benchmarks/Isolate/dart2/Isolate.dart
index 24e102b..7014df6 100644
--- a/benchmarks/Isolate/dart2/Isolate.dart
+++ b/benchmarks/Isolate/dart2/Isolate.dart
@@ -38,46 +38,6 @@
SendReceiveHelper helper;
}
-// Identical to BenchmarkBase from package:benchmark_harness but async.
-abstract class AsyncBenchmarkBase {
- final String name;
- final ScoreEmitter emitter;
-
- Future<void> run();
- Future<void> setup();
- Future<void> teardown();
-
- const AsyncBenchmarkBase(this.name, {this.emitter = const PrintEmitter()});
-
- // Returns the number of microseconds per call.
- Future<double> measureFor(int minimumMillis) async {
- final minimumMicros = minimumMillis * 1000;
- int iter = 0;
- final watch = Stopwatch();
- watch.start();
- int elapsed = 0;
- while (elapsed < minimumMicros) {
- await run();
- elapsed = watch.elapsedMicroseconds;
- iter++;
- }
- return elapsed / iter;
- }
-
- // Measures the score for the benchmark and returns it.
- Future<double> measure() async {
- await setup();
- await measureFor(500); // warm-up
- final result = await measureFor(4000); // actual measurement
- await teardown();
- return result;
- }
-
- Future<void> report() async {
- emitter.emit(name, await measure());
- }
-}
-
class StartMessage {
final SendPort sendPort;
final bool useTransferable;
diff --git a/pkg/dart2wasm/lib/compile.dart b/pkg/dart2wasm/lib/compile.dart
index 3389156..6e2c88b 100644
--- a/pkg/dart2wasm/lib/compile.dart
+++ b/pkg/dart2wasm/lib/compile.dart
@@ -10,6 +10,7 @@
CompilerResult,
DiagnosticMessage,
kernelForProgram,
+ NnbdMode,
Severity;
import 'package:kernel/ast.dart';
@@ -49,7 +50,8 @@
..sdkRoot = sdkRoot
..environmentDefines = {}
..verbose = false
- ..onDiagnostic = diagnosticMessageHandler;
+ ..onDiagnostic = diagnosticMessageHandler
+ ..nnbdMode = NnbdMode.Strong;
CompilerResult? compilerResult =
await kernelForProgram(mainUri, compilerOptions);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index d914a49..fda68ec 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -47,6 +47,7 @@
show RedirectingFactoryBody, redirectingName;
import '../kernel/type_algorithms.dart' show computeTypeVariableBuilderVariance;
import '../kernel/utils.dart' show compareProcedures;
+import '../identifiers.dart';
import '../names.dart' show equalsName, noSuchMethodName;
import '../problems.dart' show unexpected, unhandled, unimplemented;
import '../scope.dart';
@@ -1821,8 +1822,43 @@
}
if (declaration is RedirectingFactoryBuilder) {
// Compute the immediate redirection target, not the effective.
+
ConstructorReferenceBuilder redirectionTarget =
declaration.redirectionTarget;
+ List<TypeBuilder>? typeArguments = redirectionTarget.typeArguments;
+ Builder? target = redirectionTarget.target;
+ if (typeArguments != null && target is MemberBuilder) {
+ Object? redirectionTargetName = redirectionTarget.name;
+ if (redirectionTargetName is String) {
+ // Do nothing. This is the case of an identifier followed by
+ // type arguments, such as the following:
+ // B<T>
+ // B<T>.named
+ } else if (redirectionTargetName is QualifiedName) {
+ if (target.name.isEmpty) {
+ // Do nothing. This is the case of a qualified
+ // non-constructor prefix (for example, with a library
+ // qualifier) followed by type arguments, such as the
+ // following:
+ // lib.B<T>
+ } else if (target.name != redirectionTargetName.suffix.lexeme) {
+ // Do nothing. This is the case of a qualified
+ // non-constructor prefix followed by type arguments followed
+ // by a constructor name, such as the following:
+ // lib.B<T>.named
+ } else {
+ // TODO(cstefantsova,johnniwinther): Handle this in case in
+ // ConstructorReferenceBuilder.resolveIn and unify with other
+ // cases of handling of type arguments after constructor
+ // names.
+ addProblem(
+ messageConstructorWithTypeArguments,
+ redirectionTargetName.charOffset,
+ redirectionTargetName.name.length);
+ }
+ }
+ }
+
// ignore: unnecessary_null_comparison
if (redirectionTarget != null) {
Builder? targetBuilder = redirectionTarget.target;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 7da2ade..3745736 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -4195,12 +4195,15 @@
DartType tearOffType,
Expression expression) {
if (implicitInstantiation != null) {
+ FunctionType uninstantiatedType = implicitInstantiation.functionType;
+
List<DartType> typeArguments = implicitInstantiation.typeArguments;
if (!isTopLevel) {
- checkBoundsInInstantiation(implicitInstantiation.functionType,
- typeArguments, expression.fileOffset,
+ checkBoundsInInstantiation(
+ uninstantiatedType, typeArguments, expression.fileOffset,
inferred: true);
}
+
if (expression is TypedefTearOff) {
Substitution substitution =
Substitution.fromPairs(expression.typeParameters, typeArguments);
@@ -4220,9 +4223,32 @@
expression = loweredTypedefTearOff.targetTearOff;
}
}
- expression = new Instantiation(expression, typeArguments)
- ..fileOffset = expression.fileOffset;
tearOffType = implicitInstantiation.instantiatedType;
+ if (uninstantiatedType.isPotentiallyNullable) {
+ // Replace expression with:
+ // `let t = expression in t == null ? null : t<...>`
+ VariableDeclaration t = new VariableDeclaration.forValue(expression,
+ type: uninstantiatedType)
+ ..fileOffset = expression.fileOffset;
+
+ Expression nullCheck = new EqualsNull(
+ new VariableGet(t)..fileOffset = expression.fileOffset)
+ ..fileOffset = expression.fileOffset;
+
+ ConditionalExpression conditional = new ConditionalExpression(
+ nullCheck,
+ new NullLiteral()..fileOffset = expression.fileOffset,
+ new Instantiation(
+ new VariableGet(t, uninstantiatedType.toNonNull()),
+ typeArguments)
+ ..fileOffset = expression.fileOffset,
+ tearOffType);
+ expression = new Let(t, conditional)
+ ..fileOffset = expression.fileOffset;
+ } else {
+ expression = new Instantiation(expression, typeArguments)
+ ..fileOffset = expression.fileOffset;
+ }
}
return new ExpressionInferenceResult(tearOffType, expression);
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.expect
index 473f61e..190b45b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.expect
@@ -40,20 +40,20 @@
self::Class c = new self::Class::•();
(core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
int Function(int, int) f = alias;
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t1 = self::alias in #t1 == null ?{(core::int, core::int) →? core::int} null : #t1{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
(core::int, core::int?) →? core::int g;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = alias;
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t2 = self::alias in #t2 == null ?{(core::int, core::int) →? core::int} null : #t2{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
(core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
int Function(int, int?) h = c;
- ^" in ((let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
+ ^" in ((let final self::Class #t3 = c in #t3 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t3.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = c;
- ^" in ((let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in ((let final self::Class #t4 = c in #t4 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t4.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
method(alias);
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t5 = self::alias in #t5 == null ?{(core::int, core::int) →? core::int} null : #t5{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.transformed.expect
index e430e5b..226de46 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.strong.transformed.expect
@@ -40,20 +40,20 @@
self::Class c = new self::Class::•();
(core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
int Function(int, int) f = alias;
- ^" in let (core::int, core::int) →? core::int #t1 = self::alias<core::int> in #t1 == null ?{(core::int, core::int) → core::int} #t1 as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int : #t1{(core::int, core::int) → core::int};
+ ^" in let (core::int, core::int) →? core::int #t1 = let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t2 = self::alias in #t2 == null ?{(core::int, core::int) →? core::int} null : #t2{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int> in #t1 == null ?{(core::int, core::int) → core::int} #t1 as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int : #t1{(core::int, core::int) → core::int};
(core::int, core::int?) →? core::int g;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = alias;
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t3 = self::alias in #t3 == null ?{(core::int, core::int) →? core::int} null : #t3{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
(core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
int Function(int, int?) h = c;
- ^" in ((let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
+ ^" in ((let final self::Class #t4 = c in #t4 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t4.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = c;
- ^" in ((let final self::Class #t3 = c in #t3 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t3.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in ((let final self::Class #t5 = c in #t5 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t5.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
method(alias);
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t6 = self::alias in #t6 == null ?{(core::int, core::int) →? core::int} null : #t6{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.expect
index 473f61e..190b45b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.expect
@@ -40,20 +40,20 @@
self::Class c = new self::Class::•();
(core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
int Function(int, int) f = alias;
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t1 = self::alias in #t1 == null ?{(core::int, core::int) →? core::int} null : #t1{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
(core::int, core::int?) →? core::int g;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = alias;
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t2 = self::alias in #t2 == null ?{(core::int, core::int) →? core::int} null : #t2{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
(core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
int Function(int, int?) h = c;
- ^" in ((let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
+ ^" in ((let final self::Class #t3 = c in #t3 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t3.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = c;
- ^" in ((let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in ((let final self::Class #t4 = c in #t4 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t4.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
method(alias);
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t5 = self::alias in #t5 == null ?{(core::int, core::int) →? core::int} null : #t5{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.modular.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.modular.expect
index 473f61e..190b45b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.modular.expect
@@ -40,20 +40,20 @@
self::Class c = new self::Class::•();
(core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
int Function(int, int) f = alias;
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t1 = self::alias in #t1 == null ?{(core::int, core::int) →? core::int} null : #t1{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int) → core::int;
(core::int, core::int?) →? core::int g;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = alias;
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t2 = self::alias in #t2 == null ?{(core::int, core::int) →? core::int} null : #t2{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
(core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
int Function(int, int?) h = c;
- ^" in ((let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
+ ^" in ((let final self::Class #t3 = c in #t3 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t3.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = c;
- ^" in ((let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
+ ^" in ((let final self::Class #t4 = c in #t4 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t4.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) →? core::int;
self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
method(alias);
- ^" in (self::alias<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
+ ^" in (let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t5 = self::alias in #t5 == null ?{(core::int, core::int) →? core::int} null : #t5{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>) as{TypeError,ForNonNullableByDefault} (core::int, core::int?) → core::int);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.transformed.expect
index b6510b1..17155b3 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart.weak.transformed.expect
@@ -40,20 +40,20 @@
self::Class c = new self::Class::•();
(core::int, core::int) → core::int f = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:16:30: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int)' because 'int Function(int, int)?' is nullable and 'int Function(int, int)' isn't.
int Function(int, int) f = alias;
- ^" in self::alias<core::int>;
+ ^" in let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t1 = self::alias in #t1 == null ?{(core::int, core::int) →? core::int} null : #t1{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>;
(core::int, core::int?) →? core::int g;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:18:7: Error: A value of type 'int Function(int, int)?' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = alias;
- ^" in self::alias<core::int>;
+ ^" in let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t2 = self::alias in #t2 == null ?{(core::int, core::int) →? core::int} null : #t2{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>;
(core::int, core::int?) → core::int h = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:19:27: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
int Function(int, int?) h = c;
- ^" in (let final self::Class #t1 = c in #t1 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t1.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>;
+ ^" in (let final self::Class #t3 = c in #t3 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t3.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>;
g = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:20:3: Error: A value of type 'int Function(int, int)' can't be assigned to a variable of type 'int Function(int, int?)?' because 'int?' is nullable and 'int' isn't.
g = c;
- ^" in (let final self::Class #t2 = c in #t2 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t2.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>;
+ ^" in (let final self::Class #t4 = c in #t4 == null ?{<T extends core::Object? = dynamic>(T%, core::int) → T%} null : #t4.{self::Class::call}{<T extends core::Object? = dynamic>(T%, core::int) → T%})<core::int>;
self::method(invalid-expression "pkg/front_end/testcases/constructor_tearoffs/implicit_instantiation_errors.dart:21:10: Error: The argument type 'int Function(int, int)?' can't be assigned to the parameter type 'int Function(int, int?)' because 'int?' is nullable and 'int' isn't.
method(alias);
- ^" in self::alias<core::int>);
+ ^" in let final <T extends core::Object? = dynamic>(T%, core::int) →? T% #t5 = self::alias in #t5 == null ?{(core::int, core::int) →? core::int} null : #t5{<T extends core::Object? = dynamic>(T%, core::int) → T%}<core::int>);
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue41842.dart b/pkg/front_end/testcases/general/issue41842.dart
new file mode 100644
index 0000000..b6f3762
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import './issue41842_lib.dart' as lib;
+
+class A<T> {
+ A();
+ factory A.foo1(int x) = B<T>; // Ok.
+ factory A.foo2(int x) = B.foo<T>; // Error.
+ factory A.foo3(int x) = B<T>.foo; // Ok.
+ factory A.foo5(int x) = B.bar<T>; // Error.
+ factory A.foo6(int x) = B<T>.bar; // Ok.
+ factory A.foo4(int x) = lib.Foo<T>; // Ok.
+ factory A.foo7(int x) = lib.Bar<T>; // Ok.
+ factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+ factory A.foo9(int x) = lib.Foo<T>.foo; // Ok.
+ factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+ factory A.foo11(int x) = lib.Foo<T>.bar; // Ok.
+ factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+ factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+}
+
+class B<T> extends A<T> {
+ B(int x);
+ B.foo(int x);
+ factory B.bar(int x) => B.foo(x);
+}
+
+void main() {
+ new B.foo<int>(24); // Error.
+}
diff --git a/pkg/front_end/testcases/general/issue41842.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue41842.dart.textual_outline.expect
new file mode 100644
index 0000000..f3bd260
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+import './issue41842_lib.dart' as lib;
+class A<T> {
+ A();
+ factory A.foo1(int x) = B<T>;
+ factory A.foo2(int x) = B.foo<T>;
+ factory A.foo3(int x) = B<T>.foo;
+ factory A.foo5(int x) = B.bar<T>;
+ factory A.foo6(int x) = B<T>.bar;
+ factory A.foo4(int x) = lib.Foo<T>;
+ factory A.foo7(int x) = lib.Bar<T>;
+ factory A.foo8(int x) = lib.Foo.foo;
+ <
+ T;
+ operator>();
+ factory A.foo9(int x) = lib.Foo<T>.foo;
+ factory A.foo10(int x) = lib.Foo.bar;
+ <
+ T;
+ operator>();
+ factory A.foo11(int x) = lib.Foo<T>.bar;
+ factory A.foo12(int x) = B<T>.foo;
+ <
+ T;
+ operator>();
+ factory A.foo13(int x) = B<T>.bar;
+ <
+ T;
+ operator>();
+}
+class B<T> extends A<T> {
+ B(int x);
+ B.foo(int x);
+ factory B.bar(int x) => B.foo(x);
+}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue41842.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue41842.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..9f90691
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import './issue41842_lib.dart' as lib;
+
+class A<T> {
+ A();
+ factory A.foo2(int x) = B.foo<T>;
+ factory A.foo3(int x) = B<T>.foo;
+ factory A.foo4(int x) = lib.Foo<T>;
+ factory A.foo5(int x) = B.bar<T>;
+ factory A.foo6(int x) = B<T>.bar;
+ factory A.foo7(int x) = lib.Bar<T>;
+}
+
+class B<T> extends A<T> {
+ B.foo(int x) {}
+ factory B.bar(int x) => B.foo(x);
+}
+
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue41842.dart.weak.expect b/pkg/front_end/testcases/general/issue41842.dart.weak.expect
new file mode 100644
index 0000000..5f68369
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842.dart.weak.expect
@@ -0,0 +1,305 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:35: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:38: Error: Expected a class member, but got '<'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator '>' should have exactly one parameter.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:36: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:39: Error: Expected a class member, but got '<'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: 'T' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Context: Previous declaration of 'T'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator '>' should have exactly one parameter.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: '>' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Context: Previous declaration of '>'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:33: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:36: Error: Expected a class member, but got '<'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: 'T' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Context: Previous declaration of 'T'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: '>' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Context: Previous declaration of '>'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:33: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:36: Error: Expected a class member, but got '<'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: 'T' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Context: Previous declaration of 'T'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: '>' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Context: Previous declaration of '>'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Conflicts with type variable 'T'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:7:9: Context: This is the type variable.
+// class A<T> {
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:10:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo2(int x) = B.foo<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:12:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo5(int x) = B.bar<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:7:7: Error: The non-abstract class 'A' is missing implementations for these members:
+// - A.>
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class A<T> {
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Context: 'A.>' is defined here.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:31:9: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// new B.foo<int>(24); // Error.
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+import "issue41842_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41842_lib.dart" as lib;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ field dynamic T = null;
+ static final field dynamic _redirecting# = <dynamic>[#C1, #C2, #C3, #C4, #C5, #C6, #C7, #C8, #C9, #C10, #C11, #C12, #C13]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ static factory foo1<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo1::T%>
+ return new self::B::•<self::A::foo1::T%>(x);
+ static factory foo2<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo2::T%>
+ return new self::B::foo<self::A::foo2::T%>(x);
+ static factory foo3<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo3::T%>
+ return new self::B::foo<self::A::foo3::T%>(x);
+ static factory foo5<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo5::T%>
+ return self::B::bar<self::A::foo5::T%>(x);
+ static factory foo6<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo6::T%>
+ return self::B::bar<self::A::foo6::T%>(x);
+ static factory foo4<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo4::T%>
+ return new iss::Foo::•<self::A::foo4::T%>(x);
+ static factory foo7<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo7::T%>
+ return iss::Bar::•<self::A::foo7::T%>(x);
+ static factory foo8<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo8::T%>
+ return new iss::Foo::foo<self::A::foo8::T%>(x);
+ abstract operator >() → dynamic;
+ static factory foo9<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo9::T%>
+ return new iss::Foo::foo<self::A::foo9::T%>(x);
+ static factory foo10<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo10::T%>
+ return iss::Foo::bar<self::A::foo10::T%>(x);
+ static factory foo11<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo11::T%>
+ return iss::Foo::bar<self::A::foo11::T%>(x);
+ static factory foo12<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo12::T%>
+ return new self::B::foo<self::A::foo12::T%>(x);
+ static factory foo13<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo13::T%>
+ return self::B::bar<self::A::foo13::T%>(x);
+}
+class B<T extends core::Object? = dynamic> extends self::A<self::B::T%> {
+ constructor •(core::int x) → self::B<self::B::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → self::B<self::B::T%>
+ : super self::A::•()
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → self::B<self::B::bar::T%>
+ return new self::B::foo<self::B::bar::T%>(x);
+}
+static method main() → void {
+ new self::B::foo<core::int>(24);
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "issue41842.dart" as self;
+
+import "org-dartlang-testcase:///issue41842.dart";
+
+class Foo<T extends core::Object? = dynamic> extends self::A<iss::Foo::T%> {
+ constructor •(core::int x) → iss::Foo<iss::Foo::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → iss::Foo<iss::Foo::T%>
+ : super self::A::•()
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Foo<iss::Foo::bar::T%>
+ return new iss::Foo::foo<iss::Foo::bar::T%>(x);
+}
+class Bar<T extends core::Object? = dynamic> extends self::A<iss::Bar::T%> {
+ constructor named(core::int x) → iss::Bar<iss::Bar::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → iss::Bar<iss::Bar::T%>
+ : super self::A::•()
+ ;
+ static factory •<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::•::T%>
+ return new iss::Bar::named<iss::Bar::•::T%>(x);
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::bar::T%>
+ return new iss::Bar::foo<iss::Bar::bar::T%>(x);
+}
+
+constants {
+ #C1 = constructor-tearoff self::A::foo1
+ #C2 = constructor-tearoff self::A::foo2
+ #C3 = constructor-tearoff self::A::foo3
+ #C4 = constructor-tearoff self::A::foo5
+ #C5 = constructor-tearoff self::A::foo6
+ #C6 = constructor-tearoff self::A::foo4
+ #C7 = constructor-tearoff self::A::foo7
+ #C8 = constructor-tearoff self::A::foo8
+ #C9 = constructor-tearoff self::A::foo9
+ #C10 = constructor-tearoff self::A::foo10
+ #C11 = constructor-tearoff self::A::foo11
+ #C12 = constructor-tearoff self::A::foo12
+ #C13 = constructor-tearoff self::A::foo13
+}
diff --git a/pkg/front_end/testcases/general/issue41842.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue41842.dart.weak.modular.expect
new file mode 100644
index 0000000..5f68369
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842.dart.weak.modular.expect
@@ -0,0 +1,305 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:35: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:38: Error: Expected a class member, but got '<'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator '>' should have exactly one parameter.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:36: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:39: Error: Expected a class member, but got '<'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: 'T' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Context: Previous declaration of 'T'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator '>' should have exactly one parameter.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: '>' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Context: Previous declaration of '>'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:33: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:36: Error: Expected a class member, but got '<'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: 'T' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Context: Previous declaration of 'T'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: '>' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Context: Previous declaration of '>'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:33: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:36: Error: Expected a class member, but got '<'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: 'T' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Context: Previous declaration of 'T'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: '>' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Context: Previous declaration of '>'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Conflicts with type variable 'T'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:7:9: Context: This is the type variable.
+// class A<T> {
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:10:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo2(int x) = B.foo<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:12:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo5(int x) = B.bar<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:7:7: Error: The non-abstract class 'A' is missing implementations for these members:
+// - A.>
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class A<T> {
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Context: 'A.>' is defined here.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:31:9: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// new B.foo<int>(24); // Error.
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+import "issue41842_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41842_lib.dart" as lib;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ field dynamic T = null;
+ static final field dynamic _redirecting# = <dynamic>[#C1, #C2, #C3, #C4, #C5, #C6, #C7, #C8, #C9, #C10, #C11, #C12, #C13]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ static factory foo1<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo1::T%>
+ return new self::B::•<self::A::foo1::T%>(x);
+ static factory foo2<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo2::T%>
+ return new self::B::foo<self::A::foo2::T%>(x);
+ static factory foo3<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo3::T%>
+ return new self::B::foo<self::A::foo3::T%>(x);
+ static factory foo5<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo5::T%>
+ return self::B::bar<self::A::foo5::T%>(x);
+ static factory foo6<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo6::T%>
+ return self::B::bar<self::A::foo6::T%>(x);
+ static factory foo4<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo4::T%>
+ return new iss::Foo::•<self::A::foo4::T%>(x);
+ static factory foo7<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo7::T%>
+ return iss::Bar::•<self::A::foo7::T%>(x);
+ static factory foo8<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo8::T%>
+ return new iss::Foo::foo<self::A::foo8::T%>(x);
+ abstract operator >() → dynamic;
+ static factory foo9<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo9::T%>
+ return new iss::Foo::foo<self::A::foo9::T%>(x);
+ static factory foo10<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo10::T%>
+ return iss::Foo::bar<self::A::foo10::T%>(x);
+ static factory foo11<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo11::T%>
+ return iss::Foo::bar<self::A::foo11::T%>(x);
+ static factory foo12<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo12::T%>
+ return new self::B::foo<self::A::foo12::T%>(x);
+ static factory foo13<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo13::T%>
+ return self::B::bar<self::A::foo13::T%>(x);
+}
+class B<T extends core::Object? = dynamic> extends self::A<self::B::T%> {
+ constructor •(core::int x) → self::B<self::B::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → self::B<self::B::T%>
+ : super self::A::•()
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → self::B<self::B::bar::T%>
+ return new self::B::foo<self::B::bar::T%>(x);
+}
+static method main() → void {
+ new self::B::foo<core::int>(24);
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "issue41842.dart" as self;
+
+import "org-dartlang-testcase:///issue41842.dart";
+
+class Foo<T extends core::Object? = dynamic> extends self::A<iss::Foo::T%> {
+ constructor •(core::int x) → iss::Foo<iss::Foo::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → iss::Foo<iss::Foo::T%>
+ : super self::A::•()
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Foo<iss::Foo::bar::T%>
+ return new iss::Foo::foo<iss::Foo::bar::T%>(x);
+}
+class Bar<T extends core::Object? = dynamic> extends self::A<iss::Bar::T%> {
+ constructor named(core::int x) → iss::Bar<iss::Bar::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → iss::Bar<iss::Bar::T%>
+ : super self::A::•()
+ ;
+ static factory •<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::•::T%>
+ return new iss::Bar::named<iss::Bar::•::T%>(x);
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::bar::T%>
+ return new iss::Bar::foo<iss::Bar::bar::T%>(x);
+}
+
+constants {
+ #C1 = constructor-tearoff self::A::foo1
+ #C2 = constructor-tearoff self::A::foo2
+ #C3 = constructor-tearoff self::A::foo3
+ #C4 = constructor-tearoff self::A::foo5
+ #C5 = constructor-tearoff self::A::foo6
+ #C6 = constructor-tearoff self::A::foo4
+ #C7 = constructor-tearoff self::A::foo7
+ #C8 = constructor-tearoff self::A::foo8
+ #C9 = constructor-tearoff self::A::foo9
+ #C10 = constructor-tearoff self::A::foo10
+ #C11 = constructor-tearoff self::A::foo11
+ #C12 = constructor-tearoff self::A::foo12
+ #C13 = constructor-tearoff self::A::foo13
+}
diff --git a/pkg/front_end/testcases/general/issue41842.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue41842.dart.weak.outline.expect
new file mode 100644
index 0000000..52a1446
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842.dart.weak.outline.expect
@@ -0,0 +1,293 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:35: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:38: Error: Expected a class member, but got '<'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator '>' should have exactly one parameter.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:36: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:39: Error: Expected a class member, but got '<'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: 'T' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Context: Previous declaration of 'T'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator '>' should have exactly one parameter.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: '>' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Context: Previous declaration of '>'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:33: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:36: Error: Expected a class member, but got '<'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: 'T' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Context: Previous declaration of 'T'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: '>' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Context: Previous declaration of '>'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:33: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:36: Error: Expected a class member, but got '<'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: 'T' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Context: Previous declaration of 'T'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: '>' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Context: Previous declaration of '>'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Conflicts with type variable 'T'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:7:9: Context: This is the type variable.
+// class A<T> {
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:10:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo2(int x) = B.foo<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:12:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo5(int x) = B.bar<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:7:7: Error: The non-abstract class 'A' is missing implementations for these members:
+// - A.>
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class A<T> {
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Context: 'A.>' is defined here.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "issue41842_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41842_lib.dart" as lib;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ field dynamic T;
+ static final field dynamic _redirecting# = <dynamic>[self::A::foo1, self::A::foo2, self::A::foo3, self::A::foo5, self::A::foo6, self::A::foo4, self::A::foo7, self::A::foo8, self::A::foo9, self::A::foo10, self::A::foo11, self::A::foo12, self::A::foo13]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ ;
+ static factory foo1<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo1::T%>
+ return new self::B::•<self::A::foo1::T%>(x);
+ static factory foo2<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo2::T%>
+ return new self::B::foo<self::A::foo2::T%>(x);
+ static factory foo3<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo3::T%>
+ return new self::B::foo<self::A::foo3::T%>(x);
+ static factory foo5<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo5::T%>
+ return self::B::bar<self::A::foo5::T%>(x);
+ static factory foo6<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo6::T%>
+ return self::B::bar<self::A::foo6::T%>(x);
+ static factory foo4<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo4::T%>
+ return new iss::Foo::•<self::A::foo4::T%>(x);
+ static factory foo7<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo7::T%>
+ return iss::Bar::•<self::A::foo7::T%>(x);
+ static factory foo8<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo8::T%>
+ return new iss::Foo::foo<self::A::foo8::T%>(x);
+ abstract operator >() → dynamic;
+ static factory foo9<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo9::T%>
+ return new iss::Foo::foo<self::A::foo9::T%>(x);
+ static factory foo10<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo10::T%>
+ return iss::Foo::bar<self::A::foo10::T%>(x);
+ static factory foo11<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo11::T%>
+ return iss::Foo::bar<self::A::foo11::T%>(x);
+ static factory foo12<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo12::T%>
+ return new self::B::foo<self::A::foo12::T%>(x);
+ static factory foo13<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo13::T%>
+ return self::B::bar<self::A::foo13::T%>(x);
+}
+class B<T extends core::Object? = dynamic> extends self::A<self::B::T%> {
+ constructor •(core::int x) → self::B<self::B::T%>
+ ;
+ constructor foo(core::int x) → self::B<self::B::T%>
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → self::B<self::B::bar::T%>
+ ;
+}
+static method main() → void
+ ;
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "issue41842.dart" as self;
+
+import "org-dartlang-testcase:///issue41842.dart";
+
+class Foo<T extends core::Object? = dynamic> extends self::A<iss::Foo::T%> {
+ constructor •(core::int x) → iss::Foo<iss::Foo::T%>
+ ;
+ constructor foo(core::int x) → iss::Foo<iss::Foo::T%>
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Foo<iss::Foo::bar::T%>
+ ;
+}
+class Bar<T extends core::Object? = dynamic> extends self::A<iss::Bar::T%> {
+ constructor named(core::int x) → iss::Bar<iss::Bar::T%>
+ ;
+ constructor foo(core::int x) → iss::Bar<iss::Bar::T%>
+ ;
+ static factory •<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::•::T%>
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::bar::T%>
+ ;
+}
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo1)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo2)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo3)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo5)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo6)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo4)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo7)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo8)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo9)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo10)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo11)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo12)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///issue41842.dart:7:7 -> ConstructorTearOffConstant(A.foo13)
+Extra constant evaluation: evaluated: 40, effectively constant: 13
diff --git a/pkg/front_end/testcases/general/issue41842.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue41842.dart.weak.transformed.expect
new file mode 100644
index 0000000..5f68369
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842.dart.weak.transformed.expect
@@ -0,0 +1,305 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:35: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:38: Error: Expected a class member, but got '<'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Error: Expected ';' after this.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Error: Operator '>' should have exactly one parameter.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:36: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:39: Error: Expected a class member, but got '<'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: Expected ';' after this.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Error: 'T' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:39: Context: Previous declaration of 'T'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: Operator '>' should have exactly one parameter.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Error: '>' is already declared in this scope.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:16:40: Context: Previous declaration of '>'.
+// factory A.foo8(int x) = lib.Foo.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:33: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:36: Error: Expected a class member, but got '<'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: Expected ';' after this.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Error: 'T' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:40: Context: Previous declaration of 'T'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Error: '>' is already declared in this scope.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:18:41: Context: Previous declaration of '>'.
+// factory A.foo10(int x) = lib.Foo.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:33: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:36: Error: Expected a class member, but got '<'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Expected ';' after this.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: 'T' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:37: Context: Previous declaration of 'T'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator declarations must be preceded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: Operator '>' should have exactly one parameter.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Error: '>' is already declared in this scope.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:20:38: Context: Previous declaration of '>'.
+// factory A.foo12(int x) = B<T>.foo<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:21:37: Error: Conflicts with type variable 'T'.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:7:9: Context: This is the type variable.
+// class A<T> {
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:10:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo2(int x) = B.foo<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:12:29: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// factory A.foo5(int x) = B.bar<T>; // Error.
+// ^^^
+//
+// pkg/front_end/testcases/general/issue41842.dart:7:7: Error: The non-abstract class 'A' is missing implementations for these members:
+// - A.>
+// Try to either
+// - provide an implementation,
+// - inherit an implementation from a superclass or mixin,
+// - mark the class as abstract, or
+// - provide a 'noSuchMethod' implementation.
+//
+// class A<T> {
+// ^
+// pkg/front_end/testcases/general/issue41842.dart:21:38: Context: 'A.>' is defined here.
+// factory A.foo13(int x) = B<T>.bar<T>; // Error. Not allowed by parser.
+// ^
+//
+// pkg/front_end/testcases/general/issue41842.dart:31:9: Error: A constructor invocation can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// new B.foo<int>(24); // Error.
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+import "issue41842_lib.dart" as iss;
+
+import "org-dartlang-testcase:///issue41842_lib.dart" as lib;
+
+class A<T extends core::Object? = dynamic> extends core::Object {
+ field dynamic T = null;
+ static final field dynamic _redirecting# = <dynamic>[#C1, #C2, #C3, #C4, #C5, #C6, #C7, #C8, #C9, #C10, #C11, #C12, #C13]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ static factory foo1<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo1::T%>
+ return new self::B::•<self::A::foo1::T%>(x);
+ static factory foo2<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo2::T%>
+ return new self::B::foo<self::A::foo2::T%>(x);
+ static factory foo3<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo3::T%>
+ return new self::B::foo<self::A::foo3::T%>(x);
+ static factory foo5<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo5::T%>
+ return self::B::bar<self::A::foo5::T%>(x);
+ static factory foo6<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo6::T%>
+ return self::B::bar<self::A::foo6::T%>(x);
+ static factory foo4<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo4::T%>
+ return new iss::Foo::•<self::A::foo4::T%>(x);
+ static factory foo7<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo7::T%>
+ return iss::Bar::•<self::A::foo7::T%>(x);
+ static factory foo8<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo8::T%>
+ return new iss::Foo::foo<self::A::foo8::T%>(x);
+ abstract operator >() → dynamic;
+ static factory foo9<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo9::T%>
+ return new iss::Foo::foo<self::A::foo9::T%>(x);
+ static factory foo10<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo10::T%>
+ return iss::Foo::bar<self::A::foo10::T%>(x);
+ static factory foo11<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo11::T%>
+ return iss::Foo::bar<self::A::foo11::T%>(x);
+ static factory foo12<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo12::T%>
+ return new self::B::foo<self::A::foo12::T%>(x);
+ static factory foo13<T extends core::Object? = dynamic>(core::int x) → self::A<self::A::foo13::T%>
+ return self::B::bar<self::A::foo13::T%>(x);
+}
+class B<T extends core::Object? = dynamic> extends self::A<self::B::T%> {
+ constructor •(core::int x) → self::B<self::B::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → self::B<self::B::T%>
+ : super self::A::•()
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → self::B<self::B::bar::T%>
+ return new self::B::foo<self::B::bar::T%>(x);
+}
+static method main() → void {
+ new self::B::foo<core::int>(24);
+}
+
+library /*isNonNullableByDefault*/;
+import self as iss;
+import "dart:core" as core;
+import "issue41842.dart" as self;
+
+import "org-dartlang-testcase:///issue41842.dart";
+
+class Foo<T extends core::Object? = dynamic> extends self::A<iss::Foo::T%> {
+ constructor •(core::int x) → iss::Foo<iss::Foo::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → iss::Foo<iss::Foo::T%>
+ : super self::A::•()
+ ;
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Foo<iss::Foo::bar::T%>
+ return new iss::Foo::foo<iss::Foo::bar::T%>(x);
+}
+class Bar<T extends core::Object? = dynamic> extends self::A<iss::Bar::T%> {
+ constructor named(core::int x) → iss::Bar<iss::Bar::T%>
+ : super self::A::•()
+ ;
+ constructor foo(core::int x) → iss::Bar<iss::Bar::T%>
+ : super self::A::•()
+ ;
+ static factory •<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::•::T%>
+ return new iss::Bar::named<iss::Bar::•::T%>(x);
+ static factory bar<T extends core::Object? = dynamic>(core::int x) → iss::Bar<iss::Bar::bar::T%>
+ return new iss::Bar::foo<iss::Bar::bar::T%>(x);
+}
+
+constants {
+ #C1 = constructor-tearoff self::A::foo1
+ #C2 = constructor-tearoff self::A::foo2
+ #C3 = constructor-tearoff self::A::foo3
+ #C4 = constructor-tearoff self::A::foo5
+ #C5 = constructor-tearoff self::A::foo6
+ #C6 = constructor-tearoff self::A::foo4
+ #C7 = constructor-tearoff self::A::foo7
+ #C8 = constructor-tearoff self::A::foo8
+ #C9 = constructor-tearoff self::A::foo9
+ #C10 = constructor-tearoff self::A::foo10
+ #C11 = constructor-tearoff self::A::foo11
+ #C12 = constructor-tearoff self::A::foo12
+ #C13 = constructor-tearoff self::A::foo13
+}
diff --git a/pkg/front_end/testcases/general/issue41842_lib.dart b/pkg/front_end/testcases/general/issue41842_lib.dart
new file mode 100644
index 0000000..5f81a10
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue41842_lib.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import './issue41842.dart';
+
+class Foo<T> extends A<T> {
+ Foo(int x);
+ Foo.foo(int x);
+ factory Foo.bar(int x) => Foo.foo(x);
+}
+
+class Bar<T> extends A<T> {
+ factory Bar(int x) => Bar.named(x);
+ Bar.named(int x);
+ Bar.foo(int x);
+ factory Bar.bar(int x) => Bar.foo(x);
+}
diff --git a/pkg/front_end/testcases/general/issue48323.dart b/pkg/front_end/testcases/general/issue48323.dart
new file mode 100644
index 0000000..f8b557c
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48323.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, 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.
+
+void Function<T>()? genericFunction;
+
+void foo(void Function()? arg) {
+ print(arg);
+}
+
+void main() {
+ foo(genericFunction);
+}
diff --git a/pkg/front_end/testcases/general/issue48323.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue48323.dart.textual_outline.expect
new file mode 100644
index 0000000..40739b4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48323.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+void Function<T>()? genericFunction;
+void foo(void Function()? arg) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue48323.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue48323.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..40739b4
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48323.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+void Function<T>()? genericFunction;
+void foo(void Function()? arg) {}
+void main() {}
diff --git a/pkg/front_end/testcases/general/issue48323.dart.weak.expect b/pkg/front_end/testcases/general/issue48323.dart.weak.expect
new file mode 100644
index 0000000..5837324
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48323.dart.weak.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field <T extends core::Object? = dynamic>() →? void genericFunction;
+static method foo(() →? void arg) → void {
+ core::print(arg);
+}
+static method main() → void {
+ self::foo(let final <T extends core::Object? = dynamic>() →? void #t1 = self::genericFunction in #t1 == null ?{() →? void} null : #t1{<T extends core::Object? = dynamic>() → void}<dynamic>);
+}
diff --git a/pkg/front_end/testcases/general/issue48323.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue48323.dart.weak.modular.expect
new file mode 100644
index 0000000..5837324
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48323.dart.weak.modular.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field <T extends core::Object? = dynamic>() →? void genericFunction;
+static method foo(() →? void arg) → void {
+ core::print(arg);
+}
+static method main() → void {
+ self::foo(let final <T extends core::Object? = dynamic>() →? void #t1 = self::genericFunction in #t1 == null ?{() →? void} null : #t1{<T extends core::Object? = dynamic>() → void}<dynamic>);
+}
diff --git a/pkg/front_end/testcases/general/issue48323.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue48323.dart.weak.outline.expect
new file mode 100644
index 0000000..99bde69
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48323.dart.weak.outline.expect
@@ -0,0 +1,9 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field <T extends core::Object? = dynamic>() →? void genericFunction;
+static method foo(() →? void arg) → void
+ ;
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/general/issue48323.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue48323.dart.weak.transformed.expect
new file mode 100644
index 0000000..5837324
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue48323.dart.weak.transformed.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field <T extends core::Object? = dynamic>() →? void genericFunction;
+static method foo(() →? void arg) → void {
+ core::print(arg);
+}
+static method main() → void {
+ self::foo(let final <T extends core::Object? = dynamic>() →? void #t1 = self::genericFunction in #t1 == null ?{() →? void} null : #t1{<T extends core::Object? = dynamic>() → void}<dynamic>);
+}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index fab8f81..259a964 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -88,6 +88,7 @@
general/invalid_operator2: FormatterCrash
general/invalid_operator: FormatterCrash
general/invalid_super_initializer: FormatterCrash
+general/issue41842: FormatterCrash
general/issue42997: FormatterCrash
general/issue43363: FormatterCrash
general/issue45490: FormatterCrash
diff --git a/sdk/lib/core/weak.dart b/sdk/lib/core/weak.dart
index 660a5eb..0da4c16 100644
--- a/sdk/lib/core/weak.dart
+++ b/sdk/lib/core/weak.dart
@@ -4,6 +4,13 @@
part of dart.core;
+// Examples can assume:
+// class DBConnection {
+// DBConnection._();
+// factory DBConnection.connect() => DBConnection._();
+// void close() {}
+// }
+
/// An [Expando] allows adding new properties to objects.
///
/// Does not work on numbers, strings, booleans, `null`, `dart:ffi` pointers,
@@ -69,6 +76,50 @@
/// Not all objects are supported as targets for weak references.
/// The [WeakReference] constructor will reject any object that is not
/// supported as an [Expando] key.
+///
+/// Use-cases like caching can benefit from using weak references. Example:
+///
+/// ```dart
+/// /// [CachedComputation] caches the computation result, weakly holding
+/// /// on to the cache.
+/// ///
+/// /// If nothing else in the program is holding on the result, and the
+/// /// garbage collector runs, the cache is purged, freeing the memory.
+/// ///
+/// /// Until the cache is purged, the computation will not run again on
+/// /// a subsequent request.
+/// ///
+/// /// Example use:
+/// /// ```
+/// /// final cached = CachedComputation(
+/// /// () => jsonDecode(someJsonSource) as Object);
+/// /// print(cached.result);
+/// /// print(cached.result);
+/// /// ```
+/// class CachedComputation<R extends Object> {
+/// final R Function() computation;
+///
+/// WeakReference<R>? _cache;
+///
+/// CachedComputation(this.computation);
+///
+/// R get result {
+/// final cachedResult = _cache?.target;
+/// if (cachedResult != null) {
+/// return cachedResult;
+/// }
+///
+/// final result = computation();
+///
+/// // WeakReferences do not support nulls, bools, numbers, and strings.
+/// if (result is! bool && result is! num && result is! String) {
+/// _cache = WeakReference(result);
+/// }
+///
+/// return result;
+/// }
+/// }
+/// ```
@Since("2.17")
abstract class WeakReference<T extends Object> {
/// Creates a [WeakReference] pointing to the given [target].
@@ -99,29 +150,26 @@
/// with the attachment's finalization token.
///
/// Example:
-/// ```dart template:none
-/// // Keep the finalizer itself reachable, otherwise might not do anything.
-/// final Finalizer<DBConnection> _finalizer = Finalizer((connection) {
-/// connection.close();
-/// });
-///
-/// /// Access the database.
-/// Database connect() {
-/// // Wraps the connection in a nicer user-facing API,
-/// // *and* closes connection if the user forgets to.
-/// var connection = _connectToDatabase();
-/// var wrapper = Database._fromConnection(connection, _finalizer);
-/// // Get finalizer callback when `wrapper` is no longer reachable.
-/// _finalizer.attach(wrapper, connection, detach: wrapper);
-/// return wrapper;
-/// }
-///
+/// ```dart
/// class Database {
-/// final DBConnection _connection;
-/// final Finalizer<Connection> _finalizer;
-/// Database._fromConnection(this._connection, this._finalizer);
+/// // Keeps the finalizer itself reachable, otherwise it might be disposed
+/// // before the finalizer callback gets a chance to run.
+/// static final Finalizer<DBConnection> _finalizer =
+/// Finalizer((connection) => connection.close());
///
-/// // Some useful methods.
+/// final DBConnection _connection;
+///
+/// Database._fromConnection(this._connection);
+///
+/// factory Database.connect() {
+/// // Wraps the connection in a nice user API,
+/// // *and* closes connection if the user forgets to.
+/// var connection = DBConnection.connect();
+/// var wrapper = Database._fromConnection(connection);
+/// // Get finalizer callback when `wrapper` is no longer reachable.
+/// _finalizer.attach(wrapper, connection, detach: wrapper);
+/// return wrapper;
+/// }
///
/// void close() {
/// // User requested close.
@@ -129,6 +177,8 @@
/// // Detach from finalizer, no longer needed.
/// _finalizer.detach(this);
/// }
+///
+/// // Some useful methods.
/// }
/// ```
/// This example has an example of an external resource that needs clean-up.
@@ -145,7 +195,7 @@
/// that has that finalization token,
/// is no longer accessible to the program.
///
-/// If the finalzier *itself* becomes unreachable,
+/// If the finalizer *itself* becomes unreachable,
/// it's allowed to be garbage collected
/// and then it won't trigger any further callbacks.
/// Always make sure to keep the finalizer itself reachable while it's needed.
@@ -163,6 +213,10 @@
/// but as high-level events similar to timer events.
///
/// Finalization callbacks must not throw.
+///
+/// When running on the Dart native runtime, and the callback is a native
+/// function rather than a Dart function, use `dart:ffi`'s [NativeFinalizer]
+/// instead.
@Since("2.17")
abstract class Finalizer<T> {
/// Creates a finalizer with the given finalization callback.
@@ -189,18 +243,28 @@
/// They may be the *same* object.
///
/// Example:
- /// ```dart template:top
- /// /// Access the data base.
- /// Database connect() {
- /// // Wraps the connection in a nice user API,
- /// // *and* closes connection if the user forgets to.
- /// var connection = _connectToDatabase();
- /// var wrapper = Database._fromConnection(connection, _finalizer);
- /// // Get finalizer callback when `wrapper` is no longer reachable.
- /// _finalizer.attach(wrapper, connection, detach: wrapper);
- /// return wrapper;
+ /// ```dart
+ /// class Database {
+ /// // Keeps the finalizer itself reachable, otherwise it might be disposed
+ /// // before the finalizer callback gets a chance to run.
+ /// static final Finalizer<DBConnection> _finalizer =
+ /// Finalizer((connection) => connection.close());
+ ///
+ /// factory Database.connect() {
+ /// // Wraps the connection in a nice user API,
+ /// // *and* closes connection if the user forgets to.
+ /// var connection = DBConnection.connect();
+ /// var wrapper = Database._fromConnection();
+ /// // Get finalizer callback when `wrapper` is no longer reachable.
+ /// _finalizer.attach(wrapper, connection, detach: wrapper);
+ /// return wrapper;
+ /// }
+ ///
+ /// Database._fromConnection();
+ ///
+ /// // Some useful methods.
/// }
- /// ````
+ /// ```
///
/// Multiple objects may be attached using the same finalization token,
/// and the finalizer can be attached multiple times to the same object
@@ -221,17 +285,16 @@
/// if the object become inaccessible.
///
/// Example:
- /// ```dart template:none
- /// final Finalizer<DBConnection> _finalizer = Finalizer((connection) {
- /// connection.close();
- /// });
- ///
+ /// ```dart
/// class Database {
- /// final DBConnection _connection;
- /// final Finalizer<Connection> _finalizer;
- /// Database._fromConnection(this._connection, this._finalizer);
+ /// // Keeps the finalizer itself reachable, otherwise it might be disposed
+ /// // before the finalizer callback gets a chance to run.
+ /// static final Finalizer<DBConnection> _finalizer =
+ /// Finalizer((connection) => connection.close());
///
- /// // Some useful methods.
+ /// final DBConnection _connection;
+ ///
+ /// Database._fromConnection(this._connection);
///
/// void close() {
/// // User requested close.
@@ -240,6 +303,8 @@
/// // Was attached using this object as `detach` token.
/// _finalizer.detach(this);
/// }
+ ///
+ /// // Some useful methods.
/// }
/// ```
void detach(Object detach);
diff --git a/sdk/lib/ffi/native_finalizer.dart b/sdk/lib/ffi/native_finalizer.dart
index fcc4437..672b427 100644
--- a/sdk/lib/ffi/native_finalizer.dart
+++ b/sdk/lib/ffi/native_finalizer.dart
@@ -247,6 +247,96 @@
/// attached finalizers are definitely called at least once before the program
/// ends, and the callbacks are called as soon as possible after an object
/// is recognized as inaccessible.
+///
+/// When the callback is a Dart function rather than a native function, use
+/// [Finalizer] instead.
+///
+/// A native finalizer can be used to close native resources. See the following
+/// example.
+///
+/// ```dart
+/// /// [Database] enables interacting with the native database.
+/// ///
+/// /// After [close] is called, cannot be used to [query].
+/// ///
+/// /// If a [Database] is garbage collected, it is automatically closed by
+/// /// means of a native finalizer. Prefer closing manually for timely
+/// /// release of native resources.
+/// ///
+/// /// Note this class is incomplete and for illustration purposes only.
+/// class Database implements Finalizable {
+/// /// The native finalizer runs [_closeDatabasePointer] on [_nativeDatabase]
+/// /// if the object is garbage collected.
+/// ///
+/// /// Keeps the finalizer itself reachable, otherwise it might be disposed
+/// /// before the finalizer callback gets a chance to run.
+/// static final _finalizer =
+/// NativeFinalizer(_nativeDatabaseBindings.closeDatabaseAddress.cast());
+///
+/// /// The native resource.
+/// ///
+/// /// Should be closed exactly once with [_closeDatabase] or
+/// /// [_closeDatabasePointer].
+/// Pointer<_NativeDatabase> _nativeDatabase;
+///
+/// /// Used to prevent double close and usage after close.
+/// bool _closed = false;
+///
+/// Database._(this._nativeDatabase);
+///
+/// /// Open a database.
+/// factory Database.open() {
+/// final nativeDatabase = _nativeDatabaseBindings.openDatabase();
+/// final database = Database._(nativeDatabase);
+/// _finalizer.attach(database, nativeDatabase.cast(), detach: database);
+/// return database;
+/// }
+///
+/// /// Closes this database.
+/// ///
+/// /// This database cannot be used anymore after it is closed.
+/// void close() {
+/// if (_closed) {
+/// return;
+/// }
+/// _closed = true;
+/// _finalizer.detach(this);
+/// _nativeDatabaseBindings.closeDatabase(_nativeDatabase);
+/// }
+///
+/// /// Query the database.
+/// ///
+/// /// The database should not have been closed.
+/// void query() {
+/// if (_closed) {
+/// throw StateError('The database has been closed.');
+/// }
+///
+/// // Query the database.
+/// }
+/// }
+///
+/// final _nativeDatabaseBindings = _NativeDatabaseLib(DynamicLibrary.process());
+///
+/// // The following classes are typically generated with `package:ffigen`.
+/// // Use `symbol-address` to expose the address of the close function.
+/// class _NativeDatabaseLib {
+/// final DynamicLibrary _library;
+///
+/// _NativeDatabaseLib(this._library);
+///
+/// late final openDatabase = _library.lookupFunction<
+/// Pointer<_NativeDatabase> Function(),
+/// Pointer<_NativeDatabase> Function()>('OpenDatabase');
+/// late final closeDatabaseAddress =
+/// _library.lookup<NativeFunction<Void Function(Pointer<_NativeDatabase>)>>(
+/// 'CloseDatabase');
+/// late final closeDatabase = closeDatabaseAddress
+/// .asFunction<void Function(Pointer<_NativeDatabase>)>();
+/// }
+///
+/// class _NativeDatabase extends Opaque {}
+/// ```
@Since('2.17')
abstract class NativeFinalizer {
/// Creates a finalizer with the given finalization callback.
diff --git a/tools/VERSION b/tools/VERSION
index c8e491d..b748ba7 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 76
+PRERELEASE 77
PRERELEASE_PATCH 0
\ No newline at end of file