Version 2.12.0-164.0.dev

Merge commit '6b7442ce14d66c1b77dcea248c93c44fd25990ae' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 75a633f..2c8ad78 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -1105,6 +1105,8 @@
         node.hasImplicitReturnType ? null : node.function.returnType;
     DartType inferredType =
         visitFunctionNode(node.function, null, returnContext, node.fileOffset);
+    inferrer.library.checkBoundsInFunctionNode(node.function,
+        inferrer.typeSchemaEnvironment, inferrer.library.fileUri);
     node.variable.type = inferredType;
     inferrer.flowAnalysis.functionExpression_end();
     return const StatementInferenceResult();
@@ -1116,6 +1118,11 @@
     inferrer.flowAnalysis.functionExpression_begin(node);
     DartType inferredType =
         visitFunctionNode(node.function, typeContext, null, node.fileOffset);
+    // In anonymous functions the return type isn't declared, so
+    // it shouldn't be checked.
+    inferrer.library.checkBoundsInFunctionNode(
+        node.function, inferrer.typeSchemaEnvironment, inferrer.library.fileUri,
+        skipReturnType: true);
     inferrer.flowAnalysis.functionExpression_end();
     return new ExpressionInferenceResult(inferredType, node);
   }
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 5949536..a57f05f 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -3431,7 +3431,8 @@
       List<VariableDeclaration> positionalParameters,
       List<VariableDeclaration> namedParameters,
       DartType returnType,
-      int requiredParameterCount}) {
+      int requiredParameterCount,
+      bool skipReturnType = false}) {
     if (typeParameters != null) {
       for (TypeParameter parameter in typeParameters) {
         checkBoundsInType(
@@ -3455,7 +3456,7 @@
             allowSuperBounded: true);
       }
     }
-    if (returnType != null) {
+    if (!skipReturnType && returnType != null) {
       final DartType bottomType = isNonNullableByDefault
           ? const NeverType(Nullability.nonNullable)
           : const NullType();
@@ -3528,14 +3529,16 @@
   }
 
   void checkBoundsInFunctionNode(
-      FunctionNode function, TypeEnvironment typeEnvironment, Uri fileUri) {
+      FunctionNode function, TypeEnvironment typeEnvironment, Uri fileUri,
+      {bool skipReturnType = false}) {
     checkBoundsInFunctionNodeParts(
         typeEnvironment, fileUri, function.fileOffset,
         typeParameters: function.typeParameters,
         positionalParameters: function.positionalParameters,
         namedParameters: function.namedParameters,
         returnType: function.returnType,
-        requiredParameterCount: function.requiredParameterCount);
+        requiredParameterCount: function.requiredParameterCount,
+        skipReturnType: skipReturnType);
   }
 
   void checkBoundsInListLiteral(
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 96f5f94..0e029cd 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -48,8 +48,10 @@
 bail
 bailing
 bailout
+barbar
 bash
 bat
+bazbaz
 bbb
 bc
 bench
@@ -758,3 +760,4 @@
 year
 yxxx
 yy
+zz
diff --git a/pkg/front_end/testcases/general/issue44476.dart b/pkg/front_end/testcases/general/issue44476.dart
new file mode 100644
index 0000000..d8459e2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue44476.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<X extends int> {}
+
+foo(A<num> x) {
+  bar(A<num> y) {
+    barbar(A<num> yy) => null;
+  }
+  var baz = (A<num> z) {
+    var bazbaz = (A<num> zz) => null;
+  };
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue44476.dart.outline.expect b/pkg/front_end/testcases/general/issue44476.dart.outline.expect
new file mode 100644
index 0000000..7f40fcf
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue44476.dart.outline.expect
@@ -0,0 +1,33 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue44476.dart:7:12: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num> x) {
+//            ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::int* = core::int*> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X*>*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method foo(self::A<core::num*>* x) → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue44476.dart.strong.expect b/pkg/front_end/testcases/general/issue44476.dart.strong.expect
new file mode 100644
index 0000000..136f9b1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue44476.dart.strong.expect
@@ -0,0 +1,88 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue44476.dart:7:12: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num> x) {
+//            ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:9:19: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//     barbar(A<num> yy) => null;
+//                   ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:8:14: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   bar(A<num> y) {
+//              ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:12:26: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//     var bazbaz = (A<num> zz) => null;
+//                          ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:12:9: Error: Inferred type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     var bazbaz = (A<num> zz) => null;
+//         ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:11:21: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   var baz = (A<num> z) {
+//                     ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:11:7: Error: Inferred type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   var baz = (A<num> z) {
+//       ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::int* = core::int*> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X*>*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method foo(self::A<core::num*>* x) → dynamic {
+  function bar(self::A<core::num*>* y) → Null {
+    function barbar(self::A<core::num*>* yy) → Null
+      return null;
+  }
+  (self::A<core::num*>*) →* Null baz = (self::A<core::num*>* z) → Null {
+    (self::A<core::num*>*) →* Null bazbaz = (self::A<core::num*>* zz) → Null => null;
+  };
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue44476.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue44476.dart.strong.transformed.expect
new file mode 100644
index 0000000..136f9b1
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue44476.dart.strong.transformed.expect
@@ -0,0 +1,88 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue44476.dart:7:12: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num> x) {
+//            ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:9:19: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//     barbar(A<num> yy) => null;
+//                   ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:8:14: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   bar(A<num> y) {
+//              ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:12:26: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//     var bazbaz = (A<num> zz) => null;
+//                          ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:12:9: Error: Inferred type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     var bazbaz = (A<num> zz) => null;
+//         ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:11:21: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+//   var baz = (A<num> z) {
+//                     ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+// pkg/front_end/testcases/general/issue44476.dart:11:7: Error: Inferred type argument 'num' doesn't conform to the bound 'int' of the type variable 'X' on 'A'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   var baz = (A<num> z) {
+//       ^
+// pkg/front_end/testcases/general/issue44476.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends int> {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::int* = core::int*> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X*>*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method foo(self::A<core::num*>* x) → dynamic {
+  function bar(self::A<core::num*>* y) → Null {
+    function barbar(self::A<core::num*>* yy) → Null
+      return null;
+  }
+  (self::A<core::num*>*) →* Null baz = (self::A<core::num*>* z) → Null {
+    (self::A<core::num*>*) →* Null bazbaz = (self::A<core::num*>* zz) → Null => null;
+  };
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue44476.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue44476.dart.textual_outline.expect
new file mode 100644
index 0000000..c3257fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue44476.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<X extends int> {}
+
+foo(A<num> x) {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue44476.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue44476.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c3257fc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue44476.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<X extends int> {}
+
+foo(A<num> x) {}
+main() {}
diff --git a/tools/VERSION b/tools/VERSION
index f8fc983..3b233a1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 163
+PRERELEASE 164
 PRERELEASE_PATCH 0
\ No newline at end of file