Version 2.15.0-105.0.dev

Merge commit '283ce865c835ee1058b3c8cb5679a30ba33b19cc' into 'dev'
diff --git a/DEPS b/DEPS
index 0f21607..239e999 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
   # has.
-  "co19_rev": "4aae571b0358e2f063ab68f2eb92857e31deb0b9",
+  "co19_rev": "21e89324642656dcd903e97352d9d16da6a361ee",
   "co19_2_rev": "3e1ea1af9ef293d7f6a8f3332b5c71c7072a30e0",
 
   # The internal benchmarks to use. See go/dart-benchmarks-internal
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index afe00a5..cd57df0 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -461,7 +461,7 @@
           var binPaths = _findBinFolderPaths(folder);
           String symlinkPrefix =
               _findSymlinkPrefix(provider, root, binPaths: binPaths);
-          binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
+          binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
           return BazelWorkspace._(provider, root, symlinkPrefix, readonlyRoot,
               binPaths, context.join(root, '$symlinkPrefix-genfiles'),
               lookForBuildFileSubstitutes: lookForBuildFileSubstitutes);
@@ -474,7 +474,7 @@
         var binPaths = _findBinFolderPaths(parent);
         String symlinkPrefix =
             _findSymlinkPrefix(provider, root, binPaths: binPaths);
-        binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
+        binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
         return BazelWorkspace._(
             provider,
             root,
@@ -491,7 +491,7 @@
         var binPaths = _findBinFolderPaths(folder);
         String symlinkPrefix =
             _findSymlinkPrefix(provider, root, binPaths: binPaths);
-        binPaths ??= [context.join(root, '$symlinkPrefix-bin')];
+        binPaths = binPaths..add(context.join(root, '$symlinkPrefix-bin'));
         return BazelWorkspace._(
             provider,
             root,
@@ -516,11 +516,12 @@
   /// the immediate folders found in `$root/blaze-out/` and `$root/bazel-out/`
   /// for folders named "bin".
   ///
-  /// If no "bin" folder is found in any of those locations, `null` is returned.
-  static List<String>? _findBinFolderPaths(Folder root) {
+  /// If no "bin" folder is found in any of those locations, empty list is
+  /// returned.
+  static List<String> _findBinFolderPaths(Folder root) {
     var out = _firstExistingFolder(root, ['blaze-out', 'bazel-out']);
     if (out == null) {
-      return null;
+      return [];
     }
 
     List<String> binPaths = [];
@@ -532,7 +533,7 @@
         binPaths.add(possibleBin.path);
       }
     }
-    return binPaths.isEmpty ? null : binPaths;
+    return binPaths;
   }
 
   /// Return the symlink prefix, _X_, for folders `X-bin` or `X-genfiles`.
diff --git a/pkg/analyzer/test/src/workspace/bazel_test.dart b/pkg/analyzer/test/src/workspace/bazel_test.dart
index 3e22df8..88e983e 100644
--- a/pkg/analyzer/test/src/workspace/bazel_test.dart
+++ b/pkg/analyzer/test/src/workspace/bazel_test.dart
@@ -658,6 +658,26 @@
     expect(package?.workspace, equals(workspace));
   }
 
+  void test_findPackageFor_generatedFileInBlazeOutAndBin() {
+    _addResources([
+      '/ws/blaze-out/host/bin/some/code/code.packages',
+      '/ws/blaze-out/host/bin/some/code/code.dart',
+      '/ws/blaze-bin/some/code/code.dart',
+    ]);
+    workspace = BazelWorkspace.find(
+      resourceProvider,
+      convertPath('/ws/some/code/testing'),
+    )!;
+
+    // Make sure that we can find the package of the generated file.
+    var file = workspace.findFile(convertPath('/ws/some/code/code.dart'));
+    package = workspace.findPackageFor(file!.path);
+
+    expect(package, isNotNull);
+    expect(package?.root, convertPath('/ws/some/code'));
+    expect(package?.workspace, equals(workspace));
+  }
+
   void test_findPackageFor_inBlazeOut_notPackage() {
     var path =
         convertPath('/ws/blaze-out/k8-opt/bin/news/lib/news_base.pb.dart');
@@ -858,8 +878,8 @@
         resourceProvider, convertPath('/workspace/my/module'))!;
     expect(workspace.root, convertPath('/workspace'));
     expect(workspace.readonly, isNull);
-    expect(workspace.binPaths.single,
-        convertPath('/workspace/blaze-out/host/bin'));
+    expect(
+        workspace.binPaths.first, convertPath('/workspace/blaze-out/host/bin'));
     expect(workspace.genfiles, convertPath('/workspace/blaze-genfiles'));
     expect(
         workspace
@@ -893,11 +913,12 @@
         resourceProvider, convertPath('/workspace/my/module'))!;
     expect(workspace.root, convertPath('/workspace'));
     expect(workspace.readonly, isNull);
-    expect(workspace.binPaths, hasLength(2));
+    expect(workspace.binPaths, hasLength(3));
     expect(workspace.binPaths,
         contains(convertPath('/workspace/blaze-out/host/bin')));
     expect(workspace.binPaths,
         contains(convertPath('/workspace/blaze-out/k8-fastbuild/bin')));
+    expect(workspace.binPaths, contains(convertPath('/workspace/blaze-bin')));
     expect(workspace.genfiles, convertPath('/workspace/blaze-genfiles'));
   }
 
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index 17946b6..4ca88ae 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -1,4 +1,3 @@
-// @dart = 2.9
 /// This file contains code to generate scanner and parser message
 /// based on the information in pkg/front_end/messages.yaml.
 ///
@@ -168,7 +167,7 @@
     }
     sortedErrorCodes.sort();
     for (var errorCode in sortedErrorCodes) {
-      final entry = entryMap[errorCode];
+      final entry = entryMap[errorCode]!;
       final className = nameForEntry(entry)[0];
       out.writeln();
       out.writeln('const $className _$errorCode =');
@@ -188,7 +187,7 @@
   }
 
   void generateFastaAnalyzerErrorCodeList() {
-    final sorted = List<Map>.filled(translatedEntries.length, null);
+    final sorted = List<Map?>.filled(translatedEntries.length, null);
     for (var entry in translatedEntries) {
       var index = entry['index'];
       if (index is int && index >= 1 && index <= sorted.length) {
@@ -201,7 +200,7 @@
     }
     out.writeln('final fastaAnalyzerErrorCodes = <ErrorCode?>[null,');
     for (var entry in sorted) {
-      List<String> name = nameForEntry(entry);
+      List<String> name = nameForEntry(entry!);
       out.writeln('_${name[1]},');
     }
     out.writeln('];');
@@ -266,7 +265,7 @@
       print('');
       print('The following ParserErrorCodes could be auto generated:');
       for (String analyzerName in analyzerToFasta.keys.toList()..sort()) {
-        List<String> fastaNames = analyzerToFasta[analyzerName];
+        List<String> fastaNames = analyzerToFasta[analyzerName]!;
         if (fastaNames.length == 1) {
           print('  $analyzerName = ${fastaNames.first}');
         } else {
@@ -283,7 +282,7 @@
     Token token = scanString(parserSource).tokens;
     while (!token.isEof) {
       if (token.isIdentifier) {
-        String fastaErrorCode;
+        String? fastaErrorCode;
         String lexeme = token.lexeme;
         if (lexeme.length > 7) {
           if (lexeme.startsWith('message')) {
@@ -299,7 +298,7 @@
           untranslatedFastaErrorCodes.add(fastaErrorCode);
         }
       }
-      token = token.next;
+      token = token.next!;
     }
     if (untranslatedFastaErrorCodes.isNotEmpty) {
       print('');
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index c0e53d5..82b4c61 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -989,57 +989,70 @@
 void Precompiler::AddCalleesOfHelper(const Object& entry,
                                      String* temp_selector,
                                      Class* temp_cls) {
-  const intptr_t cid = entry.GetClassId();
-  if ((cid == kOneByteStringCid) || (cid == kNullCid)) {
-    // Skip common leaf constants early in order to
-    // process object pools faster.
-    return;
-  }
-  if (entry.IsUnlinkedCall()) {
-    const auto& call_site = UnlinkedCall::Cast(entry);
-    // A dynamic call.
-    *temp_selector = call_site.target_name();
-    AddSelector(*temp_selector);
-    if (IsPotentialClosureCall(*temp_selector)) {
-      const Array& arguments_descriptor =
-          Array::Handle(Z, call_site.arguments_descriptor());
-      AddClosureCall(*temp_selector, arguments_descriptor);
-    }
-  } else if (entry.IsMegamorphicCache()) {
-    // A dynamic call.
-    const auto& cache = MegamorphicCache::Cast(entry);
-    *temp_selector = cache.target_name();
-    AddSelector(*temp_selector);
-    if (IsPotentialClosureCall(*temp_selector)) {
-      const Array& arguments_descriptor =
-          Array::Handle(Z, cache.arguments_descriptor());
-      AddClosureCall(*temp_selector, arguments_descriptor);
-    }
-  } else if (entry.IsField()) {
-    // Potential need for field initializer.
-    const auto& field = Field::Cast(entry);
-    AddField(field);
-  } else if (entry.IsInstance()) {
-    // Const object, literal or args descriptor.
-    const auto& instance = Instance::Cast(entry);
-    AddConstObject(instance);
-  } else if (entry.IsFunction()) {
-    // Local closure function.
-    const auto& target = Function::Cast(entry);
-    AddFunction(target, RetainReasons::kLocalClosure);
-    if (target.IsFfiTrampoline()) {
-      const auto& callback_target =
-          Function::Handle(Z, target.FfiCallbackTarget());
-      if (!callback_target.IsNull()) {
-        AddFunction(callback_target, RetainReasons::kFfiCallbackTarget);
+  switch (entry.GetClassId()) {
+    case kOneByteStringCid:
+    case kNullCid:
+      // Skip common leaf constants early in order to
+      // process object pools faster.
+      return;
+    case kUnlinkedCallCid: {
+      const auto& call_site = UnlinkedCall::Cast(entry);
+      // A dynamic call.
+      *temp_selector = call_site.target_name();
+      AddSelector(*temp_selector);
+      if (IsPotentialClosureCall(*temp_selector)) {
+        const Array& arguments_descriptor =
+            Array::Handle(Z, call_site.arguments_descriptor());
+        AddClosureCall(*temp_selector, arguments_descriptor);
       }
+      break;
     }
-  } else if (entry.IsCode()) {
-    const auto& target_code = Code::Cast(entry);
-    if (target_code.IsAllocationStubCode()) {
-      *temp_cls ^= target_code.owner();
-      AddInstantiatedClass(*temp_cls);
+    case kMegamorphicCacheCid: {
+      // A dynamic call.
+      const auto& cache = MegamorphicCache::Cast(entry);
+      *temp_selector = cache.target_name();
+      AddSelector(*temp_selector);
+      if (IsPotentialClosureCall(*temp_selector)) {
+        const Array& arguments_descriptor =
+            Array::Handle(Z, cache.arguments_descriptor());
+        AddClosureCall(*temp_selector, arguments_descriptor);
+      }
+      break;
     }
+    case kFieldCid: {
+      // Potential need for field initializer.
+      const auto& field = Field::Cast(entry);
+      AddField(field);
+      break;
+    }
+    case kFunctionCid: {
+      // Local closure function.
+      const auto& target = Function::Cast(entry);
+      AddFunction(target, RetainReasons::kLocalClosure);
+      if (target.IsFfiTrampoline()) {
+        const auto& callback_target =
+            Function::Handle(Z, target.FfiCallbackTarget());
+        if (!callback_target.IsNull()) {
+          AddFunction(callback_target, RetainReasons::kFfiCallbackTarget);
+        }
+      }
+      break;
+    }
+    case kCodeCid: {
+      const auto& target_code = Code::Cast(entry);
+      if (target_code.IsAllocationStubCode()) {
+        *temp_cls ^= target_code.owner();
+        AddInstantiatedClass(*temp_cls);
+      }
+      break;
+    }
+    default:
+      if (entry.IsInstance()) {
+        // Const object, literal or args descriptor.
+        const auto& instance = Instance::Cast(entry);
+        AddConstObject(instance);
+      }
+      break;
   }
 }
 
diff --git a/tests/language/const/instantiated_function_constant_error_test.dart b/tests/language/const/instantiated_function_constant_error_test.dart
new file mode 100644
index 0000000..91b5ec4
--- /dev/null
+++ b/tests/language/const/instantiated_function_constant_error_test.dart
@@ -0,0 +1,180 @@
+// 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.
+
+// SharedOptions=--enable-experiment=constructor-tearoffs
+
+// Test the support for error detection with generic function instantiation
+// expressions that are constant or potentially constant. Include both some
+// explicit generic function instantiations, and some implicit ones (for the
+// latter, the type arguments are derived by type inference based on the
+// context type). The main goal is to test the new feature where the underlying
+// function is given as an existing function object, which also implies that
+// there are several new possible syntactic forms, e.g., `(b ? f1 : f2)<int>`.
+// The errors generally arise because one or more subexpressions are not
+// constant.
+
+import 'instantiated_function_constant_test.dart' as prefix;
+
+void f1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
+void f2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
+
+const b = true;
+
+const c01 = f1;
+const c02 = f2;
+
+void test<Z extends num>() {
+  void g1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
+  void g2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
+
+  // Explicitly instantiate function declaration.
+
+  const c03 = f1<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c04 = prefix.f2<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c05 = prefix.f1<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c06 = f2<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c07 = g1<int>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c08 = prefix.g2<int>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c09 = prefix.g1<int>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c10 = g2<int>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c11 = g1<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c12 = prefix.g2<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c13 = prefix.g1<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c14 = g2<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Explicitly instantiate constant variable.
+
+  const c07 = prefix.c01<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c08 = c02<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c09 = c01<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const c10 = prefix.c02<Z>;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Implicitly instantiate function declaration.
+
+  const void Function(Z) c11 = f1;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const void Function(Z, [int, Map<int, int>]) c12 = prefix.f2;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  // Implicitly instantiate constant variable.
+
+  const void Function(Z) c13 = prefix.c01;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  const void Function(Z, [int, Map<int, int>]) c14 = c02;
+  //^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+// Test new potentially constant expressions. A type variable is a potentially
+// constant type expression, so there are no errors in the initializer list.
+class A<U extends num> {
+  final x1, x2, x3, x4, x5, x6;
+  final void Function(U) x7;
+  final void Function(U) x8;
+  final void Function(U, [int, Map<num, Never>]) x9;
+  final void Function(U) x10;
+
+  const A(bool b)
+      : x1 = (b ? f1 : prefix.f2)<U>,
+        x2 = (b ? prefix.c01 : c02)<U>,
+        x3 = ((b ? prefix.f1 : f2))<U>,
+        x4 = ((b ? c01 : prefix.c02))<U>,
+        x5 = (null ?? f1)<U>,
+        x6 = ((c01 as dynamic) as void Function<X extends num>(X,
+            [num, List<X>]))<U>,
+        x7 = b ? f1 : f2,
+        x8 = b ? c01 : c02,
+        x9 = null ?? c02,
+        x10 =
+            (c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]);
+}
+
+void main() {
+  const ff = false;
+  const A<double>(true);
+  const A<num>(ff);
+
+  void h<V>() {
+    const A<V>(true);
+    //^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+
+    const A<V>(ff);
+    //^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+  }
+}
diff --git a/tests/language/const/instantiated_function_constant_test.dart b/tests/language/const/instantiated_function_constant_test.dart
new file mode 100644
index 0000000..b86f99d
--- /dev/null
+++ b/tests/language/const/instantiated_function_constant_test.dart
@@ -0,0 +1,85 @@
+// 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.
+
+// SharedOptions=--enable-experiment=constructor-tearoffs
+
+// Test the support for generic function instantiation with constant and
+// potentially constant expressions. Include both some explicit generic
+// function instantiations, and some implicit ones (for the latter, the type
+// arguments are derived by type inference based on the context type). The
+// main goal is to test the new feature where the underlying function is
+// given as an existing function object, which also implies that there are
+// several new possible syntactic forms, e.g., `(b ? f1 : f2)<int>`.
+
+import 'instantiated_function_constant_test.dart' as prefix;
+
+void f1<X extends num>(X x, [num n = 0, List<X> xList = const []]) {}
+void f2<Y extends num>(Y y, [int i = 1, Map<Y, Y> yMap = const {}]) {}
+
+const b = true;
+
+const c01 = f1;
+const c02 = f2;
+
+// Explicitly instantiate function declaration.
+const c03 = f1<int>;
+const c04 = prefix.f2<int>;
+const c05 = prefix.f1<int>;
+const c06 = f2<int>;
+
+// Explicitly instantiate constant variable.
+const c07 = prefix.c01<int>;
+const c08 = c02<int>;
+const c09 = c01<int>;
+const c10 = prefix.c02<int>;
+
+// Implicitly instantiate function declaration.
+const void Function(double) c11 = f1;
+const void Function(Never, [int, Map<int, int>]) c12 = prefix.f2;
+
+// Implicitly instantiate constant variable.
+const void Function(double) c13 = prefix.c01;
+const void Function(Never, [int, Map<int, int>]) c14 = c02;
+
+// Test new potentially constant expressions. A type variable is a potentially
+// constant type expression, so there are no errors in the initializer list.
+class A<U extends num> {
+  final x1, x2, x3, x4, x5, x6;
+  final void Function(U) x7;
+  final void Function(U) x8;
+  final void Function(U, [int, Map<num, Never>]) x9;
+  final void Function(U) x10;
+  final void Function(num) x11;
+  final void Function(double) x12;
+  final void Function(num, [int, Map<num, Never>]) x13;
+  final void Function(int) x14;
+
+  const A(bool b)
+      : x1 = b ? (b ? f1 : prefix.f2)<U> : (b ? f1 : prefix.f2)<int>,
+        x2 = b ? (b ? prefix.c01 : c02)<U> : (b ? prefix.c01 : c02)<int>,
+        x3 = b ? ((b ? prefix.f1 : f2))<U> : ((b ? prefix.f1 : f2))<int>,
+        x4 = b ? ((b ? c01 : prefix.c02))<U> : ((b ? c01 : prefix.c02))<int>,
+        x5 = b ? (null ?? f1)<U> : (null ?? f1)<int>,
+        x6 = b
+            ? ((c01 as dynamic) as void Function<X extends num>(X,
+                [num, List<X>]))<U>
+            : ((c01 as dynamic) as void Function<X extends num>(X,
+                [num, List<X>]))<int>,
+        x7 = b ? f1 : f2,
+        x8 = b ? c01 : c02,
+        x9 = null ?? c02,
+        x10 =
+            (c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]),
+        x11 = b ? f1 : f2,
+        x12 = b ? c01 : c02,
+        x13 = null ?? c02,
+        x14 =
+            (c01 as dynamic) as void Function<X extends num>(X, [int, List<X>]);
+}
+
+void main() {
+  const ff = false;
+  const A<double>(true);
+  const A<num>(ff);
+}
diff --git a/tools/VERSION b/tools/VERSION
index 5845878..89f18db 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 104
+PRERELEASE 105
 PRERELEASE_PATCH 0
\ No newline at end of file