Issue #996: More tests for Generic functions as type parameter or bound added, missing shared options added
diff --git a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t02.dart b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t02.dart
index a7c913d..480d83a 100644
--- a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t02.dart
+++ b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t02.dart
@@ -34,7 +34,7 @@
  * dynamically.
  * @author iarkh@unipro.ru
  */
-// SharedOptions=--enable-experiment=generic-metadata
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
 
 import "../../Utils/expect.dart";
 
diff --git a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t03.dart b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t03.dart
index d76ba3a..f471e40 100644
--- a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t03.dart
+++ b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t03.dart
@@ -35,7 +35,7 @@
  * @Issue 45065
  * @author iarkh@unipro.ru
  */
-// SharedOptions=--enable-experiment=generic-metadata
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
 
 typedef exp1 = T Function<T>(T);
 typedef exp2 = void Function<T>();
diff --git a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t04.dart b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t04.dart
index 298a337..6fc1e93 100644
--- a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t04.dart
+++ b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t04.dart
@@ -35,7 +35,7 @@
  * @Issue 45065
  * @author iarkh@unipro.ru
  */
-// SharedOptions=--enable-experiment=generic-metadata
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
 
 typedef exp1 = T Function<T>(T);
 typedef exp2 = void Function<T>();
diff --git a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t05.dart b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t05.dart
index f17b3d4..bcb8d66 100644
--- a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t05.dart
+++ b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t05.dart
@@ -35,7 +35,7 @@
  * @Issue 45065
  * @author iarkh@unipro.ru
  */
-// SharedOptions=--enable-experiment=generic-metadata
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
 
 typedef exp1 = T Function<T>(T);
 typedef exp2 = void Function<T>();
diff --git a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t06.dart b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t06.dart
index 3192981..fe24669 100644
--- a/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t06.dart
+++ b/LanguageFeatures/Generic-functions-as-type-args/typedef3_A01_t06.dart
@@ -35,7 +35,7 @@
  * @Issue 45065
  * @author iarkh@unipro.ru
  */
-// SharedOptions=--enable-experiment=generic-metadata
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
 
 typedef exp1 = T Function<T>(T);
 typedef exp2 = void Function<T>();
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t01.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t01.dart
new file mode 100644
index 0000000..e1468b3
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t01.dart
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that generic function cannot be a class type argument and
+ * bound if source is marked with "@dart=2.6" tag.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.6
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata
+
+class C1<X extends T Function<T>(T)> {}
+//       ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C2<X extends void Function<T>(T)> {}
+//       ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C3<X extends T Function<T>()> {}
+//       ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+class C4<X extends void Function<T>()> {}
+//       ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+main() {}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t02.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t02.dart
new file mode 100644
index 0000000..5dbd21f
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t02.dart
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that generic function cannot be a function typedef type
+ * argument and bound if source is marked with "@dart=2.6" tag.
+ * @Issue 45834
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.6
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata
+
+typedef F1 = void Function<X extends void Function<T>()>();
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+typedef F2 = void Function<X extends T Function<T>()>();
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+typedef F3 = void Function<X extends void Function<T>(T)>();
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+typedef F4 = void Function<X extends T Function<T>(T)>();
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+main() {}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t03.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t03.dart
new file mode 100644
index 0000000..1509cc8
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t03.dart
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that generic function cannot be a function type argument
+ * and bound if source is marked with "@dart=2.6" tag.
+ * @Issue 45834
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.6
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata
+
+void F1<X extends void Function<T>()>() {}
+//      ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+void F2<X extends T Function<T>()>() {}
+//      ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+void F3<X extends void Function<T>(T)>() {}
+//      ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+void F4<X extends T Function<T>(T)>() {}
+//      ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+main() {}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t04.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t04.dart
new file mode 100644
index 0000000..5a914b2
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t04.dart
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that generic function cannot be a old-style function type
+ * alias type argument and bound if source is marked with "@dart=2.9" tag.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+typedef G1<X extends void Function<T>()>();
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+typedef G2<X extends T Function<T>()>();
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+typedef G3<X extends void Function<T>(T)>();
+//         ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+typedef G4 <X extends T Function<T>(T)>();
+//          ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+main() {}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t05.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t05.dart
new file mode 100644
index 0000000..35bda37
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t05.dart
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that generic function cannot be a class type argument and
+ * bound if source is marked with "@dart=2.6" tag.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata
+
+class C<T> {}
+
+main() {
+  C<T Function<T>(T)> c1 = throw "Should not reach here";
+//                    ^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C<T Function<T>(T)>();
+//  ^^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C<T Function<T>()> c2 = throw "Should not reach here";
+//                   ^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C<T Function<T>()>();
+//  ^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C<void Function<T>(T)> c3 = throw "Should not reach here";
+//                       ^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C<void Function<T>(T)>();
+//  ^^^^^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C<void Function<T>()> c4 = throw "Should not reach here";
+//                      ^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C<void Function<T>()>();
+//  ^^^^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t06.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t06.dart
new file mode 100644
index 0000000..0874f99
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A01_t06.dart
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that generic function cannot be a function type argument
+ * and bound if source is marked with "@dart=2.6" tag.
+ * @Issue 45834
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.6
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata
+
+void F<T>() {}
+
+main() {
+  F<void Function<T>()>();
+//  ^^^^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F<T Function<T>()>();
+//  ^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F<void Function<T>(T)>();
+//  ^^^^^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F<T Function<T>(T)>();
+//  ^^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t01.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t01.dart
new file mode 100644
index 0000000..927102f
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t01.dart
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that legacy code cannot import and call a class with
+ * generic function as type parameter or bound.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+import "opted_out_lib.dart";
+
+main() {
+  C1();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C2();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C3();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C4();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C1 c1 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C2 c2 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C3 c3 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  C4 c4 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t02.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t02.dart
new file mode 100644
index 0000000..92476cf
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t02.dart
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that legacy code cannot import and call a non-function
+ * type alias with generic function as type parameter or bound.
+ * @Issue 45836
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+import "opted_out_lib.dart";
+
+main() {
+  A1();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A2();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A3();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A4();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A1 c1 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A2 c2 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A3 c3 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A4 c4 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t03.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t03.dart
new file mode 100644
index 0000000..0c28b5b
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t03.dart
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that legacy code cannot import and call a non-function
+ * type alias with generic function as type parameter or bound.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+import "opted_out_lib.dart";
+
+main() {
+  A5();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A6();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A7();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A8();
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A5 c1 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A6 c2 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A7 c3 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  A8 c4 = throw "Error";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t04.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t04.dart
new file mode 100644
index 0000000..badbc62
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t04.dart
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that legacy code cannot import and call a function type
+ * alias with generic function as type parameter or bound.
+ * @Issue 45834
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+import "opted_out_lib.dart";
+
+typedef F1 = void Function<X extends void Function<T>()>();
+typedef F2 = X Function<X extends T Function<T>()>();
+typedef F3 = void Function<X extends void Function<T>(T)>(X);
+typedef F4 = void Function<X extends T Function<T>(T)>(X);
+
+main() {
+  F1 f1 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F2 f2 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F3 f3 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F4 f4 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t05.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t05.dart
new file mode 100644
index 0000000..eb45f63
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t05.dart
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that legacy code cannot import and call a function type
+ * alias with generic function as type parameter or bound.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+import "opted_out_lib.dart";
+
+main() {
+  F5 f1 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F6 f2 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F7 f3 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F8 f4 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t06.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t06.dart
new file mode 100644
index 0000000..a2f85cc
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t06.dart
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that legacy code cannot import and call an old-style
+ * function type alias with generic function as type parameter or bound.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+import "opted_out_lib.dart";
+
+main() {
+  F9 f1 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F10 f2 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F11 f3 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F12 f4 = throw "Should not reach here!";
+//^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t07.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t07.dart
new file mode 100644
index 0000000..09ed578
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/legacy_A02_t07.dart
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @assertion Allow generic function types as type arguments and bounds
+ *
+ * The language disallows generic function types as type arguments and bounds.
+ *
+ *  late List<T Function<T>(T)> idFunctions; // INVALID.
+ *  var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
+ *  late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
+ *
+ * We remove that restriction, so a type argument and a bound can be a generic
+ * function type.
+ *
+ * This requires no new syntax, and in some cases only the removal of a single
+ * check. There might be some platforms where the implementation currently
+ * assumes that generic function types cannot occur as the value of type
+ * variables (an proof-of-concept attempt hit an assert in the VM). Such
+ * assumptions will need to be flushed out with tests and fixed.
+ *
+ * Because we already infer List<T Function<T>(T)> in the code above, this
+ * change will not affect type inference, it will just make the inferred type
+ * not be an error afterwards.
+ *
+ * We do not expect the removal of this restriction to affect the feasibility of
+ * type inference. After all, it's already possible to have a generic function
+ * type occurring covariantly in a type argument, like List<T Function<T>(T)
+ * Function()>.
+ * @description Checks that legacy code cannot import and call an old-style
+ * function type alias with generic function as type parameter or bound.
+ * @author iarkh@unipro.ru
+ */
+// @dart=2.9
+// Requirements=nnbd-weak
+// SharedOptions=--enable-experiment=generic-metadata,nonfunction-type-aliases
+
+import "opted_out_lib.dart";
+
+main() {
+  F13();
+//^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F14();
+//^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F15();
+//^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+  F16();
+//^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Generic-functions-as-type-args/weak/opted_out_lib.dart b/LanguageFeatures/Generic-functions-as-type-args/weak/opted_out_lib.dart
new file mode 100644
index 0000000..67046e1
--- /dev/null
+++ b/LanguageFeatures/Generic-functions-as-type-args/weak/opted_out_lib.dart
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021, 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.
+ */
+/**
+ * @author iarkh@unipro.ru
+ */
+library opted_out_lib;
+
+class C1<X extends void Function<T>()> {}
+class C2<X extends T Function<T>()> {}
+class C3<X extends void Function<T>(T)> {}
+class C4<X extends void Function<T>()> {}
+
+class D<T> {}
+typedef A1 = D<void Function<T>()>;
+typedef A2 = D<T Function<T>()>;
+typedef A3 = D<void Function<T>(T)>;
+typedef A4 = D<T Function<T>(T)>;
+
+typedef A5<X extends void Function<T>()> = D<X>;
+typedef A6<X extends T Function<T>()> = D<X>;
+typedef A7<X extends void Function<T>(T)> = D<X>;
+typedef A8<X extends T Function<T>(T)> = D<X>;
+
+typedef F1 = void Function<X extends void Function<T>()>();
+typedef F2 = X Function<X extends T Function<T>()>();
+typedef F3 = void Function<X extends void Function<T>(T)>(X);
+typedef F4 = void Function<X extends T Function<T>(T)>(X);
+
+typedef F5<X extends void Function<T>()> = void Function();
+typedef F6<X extends T Function<T>()> = void Function();
+typedef F7<X extends void Function<T>(T)> = void Function();
+typedef F8<X extends T Function<T>(T)> = void Function();
+
+typedef void F9<X extends void Function<T>()>();
+typedef void F10<X extends void Function<T>(T)>();
+typedef void F11<X extends T Function<T>()>();
+typedef void F12<X extends T Function<T>(T)>();
+
+void F13<X extends void Function<T>()>() {}
+void F14<X extends void Function<T>(T)>() {}
+void F15<X extends T Function<T>()>() {}
+void F16<X extends T Function<T>(T)>() {}