Version 2.17.0-200.0.dev

Merge commit '76bbd199a403de16320df682a5c807797d080520' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
index c729106..ccbba42 100644
--- a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
@@ -581,9 +581,17 @@
     var rewind = _constraints.length;
 
     for (var i = 0; i < P.typeArguments.length; i++) {
+      var variance =
+          (P.element.typeParameters[i] as TypeParameterElementImpl).variance;
       var M = P.typeArguments[i];
       var N = Q.typeArguments[i];
-      if (!trySubtypeMatch(M, N, leftSchema)) {
+      if ((variance.isCovariant || variance.isInvariant) &&
+          !trySubtypeMatch(M, N, leftSchema)) {
+        _constraints.length = rewind;
+        return false;
+      }
+      if ((variance.isContravariant || variance.isInvariant) &&
+          !trySubtypeMatch(N, M, leftSchema)) {
         _constraints.length = rewind;
         return false;
       }
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 5ff9302..079b416 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -66,6 +66,7 @@
 import 'type_inference/test_all.dart' as type_inference;
 import 'type_literal_test.dart' as type_literal;
 import 'type_name_test.dart' as type_name;
+import 'variance_test.dart' as variance_test;
 import 'yield_statement_test.dart' as yield_statement;
 
 main() {
@@ -128,6 +129,7 @@
     type_inference.main();
     type_literal.main();
     type_name.main();
+    variance_test.main();
     yield_statement.main();
     defineReflectiveTests(UpdateNodeTextExpectations);
   }, name: 'resolution');
diff --git a/pkg/analyzer/test/src/dart/resolution/variance_test.dart b/pkg/analyzer/test/src/dart/resolution/variance_test.dart
new file mode 100644
index 0000000..34067a8
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/variance_test.dart
@@ -0,0 +1,102 @@
+// 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:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(VarianceTest);
+  });
+}
+
+@reflectiveTest
+class VarianceTest extends PubPackageResolutionTest {
+  @override
+  List<String> get experiments => [
+        ...super.experiments,
+        EnableString.variance,
+      ];
+
+  test_inference_in_parameter() async {
+    await assertNoErrorsInCode('''
+class Contravariant<in T> {}
+
+class Exactly<inout T> {}
+
+class Upper {}
+class Middle extends Upper {}
+
+Exactly<T> inferContraContra<T>(Contravariant<T> x, Contravariant<T> y)
+    => new Exactly<T>();
+
+main() {
+  inferContraContra(Contravariant<Upper>(), Contravariant<Middle>());
+}
+    ''');
+    assertType(
+        findNode.methodInvocation('inferContraContra(').typeArgumentTypes![0],
+        'Middle');
+  }
+
+  test_inference_in_parameter_downwards() async {
+    await assertErrorsInCode('''
+class B<in T> {
+  B(List<T> x);
+  void set x(T val) {}
+}
+
+main() {
+  B<int> b = new B(<num>[])..x=2.2;
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 76, 1),
+    ]);
+    assertType(
+        (findNode.instanceCreation('new B').staticType as InterfaceType)
+            .typeArguments[0],
+        'num');
+  }
+
+  test_inference_inout_parameter() async {
+    await assertErrorsInCode('''
+class Invariant<inout T> {}
+
+class Exactly<inout T> {}
+
+Exactly<T> inferInvInv<T>(Invariant<T> x, Invariant<T> y) => new Exactly<T>();
+
+main() {
+  inferInvInv(Invariant<String>(), Invariant<int>());
+}
+''', [
+      error(CompileTimeErrorCode.COULD_NOT_INFER, 147, 11),
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 159, 19),
+      error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 180, 16),
+    ]);
+  }
+
+  test_inference_out_parameter() async {
+    await assertNoErrorsInCode('''
+class Covariant<out T> {}
+
+class Exactly<inout T> {}
+
+class Upper {}
+class Middle extends Upper {}
+
+Exactly<T> inferCovCov<T>(Covariant<T> x, Covariant<T> y) => new Exactly<T>();
+
+main() {
+  inferCovCov(Covariant<Upper>(), Covariant<Middle>());
+}
+''');
+    assertType(findNode.methodInvocation('inferCovCov(').typeArgumentTypes![0],
+        'Upper');
+  }
+}
diff --git a/pkg/front_end/tool/fasta.dart b/pkg/front_end/tool/fasta.dart
index 14f8503..cdd5609 100644
--- a/pkg/front_end/tool/fasta.dart
+++ b/pkg/front_end/tool/fasta.dart
@@ -4,7 +4,19 @@
 
 import 'dart:io';
 
+import "package:testing/src/run_tests.dart" as run_tests;
+import 'package:kernel/src/tool/dump.dart' as dump;
 import '../test/utils/io_utils.dart' show computeRepoDir;
+import '_fasta/abcompile.dart' as abcompile;
+import '_fasta/compile.dart' as compile;
+import '_fasta/compile_platform.dart' as compile_platform;
+import '_fasta/generate_experimental_flags.dart' as generate_experimental_flags;
+import '_fasta/generate_messages.dart' as generate_messages;
+import '_fasta/log_analyzer.dart' as log_analyzer;
+import '_fasta/log_collector.dart' as log_collector;
+import '_fasta/outline.dart' as outline;
+import '_fasta/parser.dart' as parser;
+import '_fasta/scanner.dart' as scanner;
 
 final String repoDir = computeRepoDir();
 
@@ -35,62 +47,86 @@
   String command = args[index++];
   List<String> remainingArguments = args.skip(index).toList();
 
+  dynamic Function(List<String>) mainFunction;
+
   switch (command) {
     case 'abcompile':
+      mainFunction = abcompile.main;
       script = '${toolDir}/abcompile.dart';
       break;
     case 'compile':
+      mainFunction = compile.main;
       script = '${toolDir}/compile.dart';
       break;
     case 'compile-platform':
+      mainFunction = compile_platform.main;
       script = '${toolDir}/compile_platform.dart';
       break;
     case 'log':
+      mainFunction = log_analyzer.main;
       script = '${toolDir}/log_analyzer.dart';
       break;
     case 'logd':
+      mainFunction = log_collector.main;
       script = '${toolDir}/log_collector.dart';
       break;
     case 'outline':
+      mainFunction = outline.main;
       script = '${toolDir}/outline.dart';
       break;
     case 'parser':
+      mainFunction = parser.main;
       script = '${toolDir}/parser.dart';
       break;
     case 'scanner':
+      mainFunction = scanner.main;
       script = '${toolDir}/scanner.dart';
       break;
     case 'dump-ir':
+      mainFunction = dump.main;
       script = '${kernelBin}/dump.dart';
       if (remainingArguments.isEmpty || remainingArguments.length > 2) {
         stop("Usage: $command dillFile [output]");
       }
       break;
     case 'testing':
+      mainFunction = run_tests.main;
       script = '${repoDir}/pkg/testing/bin/testing.dart';
       scriptArguments.add('--config=${repoDir}/pkg/front_end/testing.json');
       break;
     case 'generate-messages':
+      mainFunction = generate_messages.main;
       script = '${toolDir}/generate_messages.dart';
       break;
     case 'generate-experimental-flags':
+      mainFunction = generate_experimental_flags.main;
       script = '${toolDir}/generate_experimental_flags.dart';
       break;
     default:
       stop("'$command' isn't a valid subcommand.");
   }
 
-  List<String> arguments = [];
-  arguments.addAll(extraVmArguments);
-  arguments.add('--enable-asserts');
-  arguments.add(script);
-  arguments.addAll(remainingArguments);
-  arguments.addAll(scriptArguments);
+  if (extraVmArguments.isNotEmpty) {
+    List<String> arguments = [];
+    arguments.addAll(extraVmArguments);
+    arguments.add('--enable-asserts');
+    arguments.add(script);
+    arguments.addAll(remainingArguments);
+    arguments.addAll(scriptArguments);
 
-  print('Running: ${dartVm} ${arguments.join(' ')}');
-  Process process = await Process.start(dartVm, arguments,
-      mode: ProcessStartMode.inheritStdio);
-  exitCode = await process.exitCode;
+    print('Running: ${dartVm} ${arguments.join(' ')}');
+    Process process = await Process.start(dartVm, arguments,
+        mode: ProcessStartMode.inheritStdio);
+    exitCode = await process.exitCode;
+  } else {
+    // Run within the same VM if no VM arguments are provided.
+    List<String> arguments = [];
+    arguments.addAll(remainingArguments);
+    arguments.addAll(scriptArguments);
+
+    print('Running: ${script} ${arguments.join(' ')}');
+    await mainFunction(arguments);
+  }
 }
 
 Never stop(String message) {
diff --git a/pkg/kernel/bin/dump.dart b/pkg/kernel/bin/dump.dart
index 0f901a2..6ef167a 100755
--- a/pkg/kernel/bin/dump.dart
+++ b/pkg/kernel/bin/dump.dart
@@ -3,30 +3,4 @@
 // 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 'dart:io';
-
-import 'package:kernel/kernel.dart';
-import 'package:kernel/src/tool/command_line_util.dart';
-
-void usage() {
-  print("Prints a dill file as a textual format.");
-  print("");
-  print("Usage: dart <script> dillFile.dill [output]");
-  print("");
-  print("The first given argument should be an existing file");
-  print("that is valid to load as a dill file.");
-  print("");
-  print("The second argument is optional.");
-  print("If given, output will be written to this file.");
-  print("If not given, output will be written to standard out.");
-  exit(1);
-}
-
-void main(List<String> args) {
-  CommandLineHelper.requireVariableArgumentCount([1, 2], args, usage);
-  CommandLineHelper.requireFileExists(args[0]);
-  var binary = CommandLineHelper.tryLoadDill(args[0]);
-  writeComponentToText(binary,
-      path: args.length > 1 ? args[1] : null,
-      showOffsets: const bool.fromEnvironment("showOffsets"));
-}
+export 'package:kernel/src/tool/dump.dart';
diff --git a/pkg/kernel/lib/src/tool/dump.dart b/pkg/kernel/lib/src/tool/dump.dart
new file mode 100644
index 0000000..dff0851
--- /dev/null
+++ b/pkg/kernel/lib/src/tool/dump.dart
@@ -0,0 +1,31 @@
+// 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 'dart:io';
+
+import '../../kernel.dart';
+import 'command_line_util.dart';
+
+void usage() {
+  print("Prints a dill file as a textual format.");
+  print("");
+  print("Usage: dart <script> dillFile.dill [output]");
+  print("");
+  print("The first given argument should be an existing file");
+  print("that is valid to load as a dill file.");
+  print("");
+  print("The second argument is optional.");
+  print("If given, output will be written to this file.");
+  print("If not given, output will be written to standard out.");
+  exit(1);
+}
+
+void main(List<String> args) {
+  CommandLineHelper.requireVariableArgumentCount([1, 2], args, usage);
+  CommandLineHelper.requireFileExists(args[0]);
+  Component binary = CommandLineHelper.tryLoadDill(args[0]);
+  writeComponentToText(binary,
+      path: args.length > 1 ? args[1] : null,
+      showOffsets: const bool.fromEnvironment("showOffsets"));
+}
diff --git a/tests/language/variance/variance_in_inference_error_test.dart b/tests/language/variance/variance_in_inference_error_test.dart
index 34c6fb3..a4c67b7 100644
--- a/tests/language/variance/variance_in_inference_error_test.dart
+++ b/tests/language/variance/variance_in_inference_error_test.dart
@@ -48,30 +48,40 @@
 //^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
+//                                 ^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 
   // String <: T <: int is not a valid constraint.
   inferCovContra(Covariant<String>(), Contravariant<int>());
 //^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
+//                                    ^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 
   // Middle <: T <: Lower is not a valid constraint
   inferCovContra(Covariant<Middle>(), Contravariant<Lower>());
 //^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
+//                                    ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 
   // Upper <: T <: Lower is not a valid constraint
   inferCovContra(Covariant<Upper>(), Contravariant<Lower>());
 //^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
+//                                   ^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 
   // Upper <: T <: Middle is not a valid constraint
   inferCovContra(Covariant<Upper>(), Contravariant<Middle>());
 //^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] unspecified
+//                                   ^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 
   // Inference for Contrabound(...) produces Lower <: T <: Upper.
   // Since T is contravariant, we choose Upper as the solution.
diff --git a/tests/language/variance/variance_inout_inference_error_test.dart b/tests/language/variance/variance_inout_inference_error_test.dart
index 8bf485f..7f51119 100644
--- a/tests/language/variance/variance_inout_inference_error_test.dart
+++ b/tests/language/variance/variance_inout_inference_error_test.dart
@@ -23,6 +23,8 @@
 main() {
   // Middle <: T <: Middle and int <: T <: int are not valid constraints.
   inferInvInv(Invariant<Middle>(), Invariant<int>());
+//^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 //            ^^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 // [cfe] The argument type 'Invariant<Middle>' can't be assigned to the parameter type 'Invariant<Object>'.
@@ -32,12 +34,16 @@
 
   // Middle <: T <: Middle and Upper <: T <: Upper are not valid constraints.
   inferInvInv(Invariant<Middle>(), Invariant<Upper>());
+//^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 //            ^^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 // [cfe] The argument type 'Invariant<Middle>' can't be assigned to the parameter type 'Invariant<Upper>'.
 
   // Middle <: T <: Middle and Lower <: T <: Lower are not valid constraints.
   inferInvInv(Invariant<Middle>(), Invariant<Lower>());
+//^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 //                                 ^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 // [cfe] The argument type 'Invariant<Lower>' can't be assigned to the parameter type 'Invariant<Middle>'.
@@ -46,6 +52,8 @@
   // Middle <: T <: Middle
   // Upper <: T <: Middle is not a valid constraint.
   inferInvCov(Invariant<Middle>(), Covariant<Upper>());
+//^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 //            ^^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 // [cfe] The argument type 'Invariant<Middle>' can't be assigned to the parameter type 'Invariant<Upper>'.
@@ -54,6 +62,8 @@
   // Middle <: T <: Lower
   // Middle <: T <: Lower is not a valid constraint
   inferInvContra(Invariant<Middle>(), Contravariant<Lower>());
+//^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 //                                    ^^^^^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
 // [cfe] The argument type 'Contravariant<Lower>' can't be assigned to the parameter type 'Contravariant<Middle>'.
diff --git a/tools/VERSION b/tools/VERSION
index a3c62a0..911a64f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 199
+PRERELEASE 200
 PRERELEASE_PATCH 0
\ No newline at end of file