Turn on the experimental feature `inference-update-1`.

Fixes https://github.com/dart-lang/language/issues/731.

Change-Id: I5fee1470efe7b891b79dcfecd33bc3670590efb3
Tested: trybots, and global presubmit in the internal mono repo
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243530
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Liam Appelbe <liama@google.com>
Reviewed-by: Michael Thomsen <mit@google.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab41e51..46f2467 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,52 @@
 ## 2.18.0
 
+### Language
+
+The following features are new in the Dart 2.18 [language version][]. To use
+them, you must set the lower bound on the SDK constraint for your package to
+2.18 or greater (`sdk: '>=2.18.0 <3.0.0'`).
+
+[language version]: https://dart.dev/guides/language/evolution
+
+-  **[Enhanced type inference for generic invocations with function
+   literals][]**: Invocations of generic methods/constructors that supply
+   function literal arguments now have improved type inference.  This primarily
+   affects the `Iterable.fold` method.  For example, in previous versions of
+   Dart, the compiler would fail to infer an appropriate type for the parameter
+   `a`:
+
+   ```dart
+   void main() {
+     List<int> ints = [1, 2, 3];
+     var maximum = ints.fold(0, (a, b) => a < b ? b : a);
+   }
+   ```
+
+   With this improvement, `a` receives its type from the initial value, `0`.
+
+   On rare occasions, the wrong type will be inferred, leading to a compile-time
+   error, for example in this code, type inference will infer that `a` has a
+   type of `Null`:
+
+   ```dart
+   void main() {
+     List<int> ints = [1, 2, 3];
+     var maximumOrNull = ints.fold(null,
+         (a, b) => a == null || a < b ? b : a);
+   }
+   ```
+
+   This can be worked around by supplying the appropriate type as an explicit
+   type argument to `fold`:
+
+   ```dart
+   void main() {
+     List<int> ints = [1, 2, 3];
+     var maximumOrNull = ints.fold<int?>(null,
+         (a, b) => a == null || a < b ? b : a);
+   }
+   ```
+
 ### Core libraries
 
 #### `dart:html`
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 0ddc93b..de04c11 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -197,7 +197,7 @@
     documentation:
         'Horizontal type inference for function expressions passed to generic invocations.',
     experimentalReleaseVersion: null,
-    releaseVersion: null,
+    releaseVersion: Version.parse('2.18.0'),
   );
 
   static final inference_update_2 = ExperimentalFeature(
@@ -350,7 +350,7 @@
   static const bool generic_metadata = true;
 
   /// Default state of the experiment "inference-update-1"
-  static const bool inference_update_1 = false;
+  static const bool inference_update_1 = true;
 
   /// Default state of the experiment "inference-update-2"
   static const bool inference_update_2 = false;
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
index 3bfd9d3..bc70279 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart
@@ -125,7 +125,7 @@
 
   static const ExperimentalFlag inferenceUpdate1 = const ExperimentalFlag(
       name: 'inference-update-1',
-      isEnabledByDefault: false,
+      isEnabledByDefault: true,
       isExpired: false,
       enabledVersion: const Version(2, 18),
       experimentEnabledVersion: const Version(2, 18),
diff --git a/runtime/vm/experimental_features.cc b/runtime/vm/experimental_features.cc
index 6ac7812..c776db0f 100644
--- a/runtime/vm/experimental_features.cc
+++ b/runtime/vm/experimental_features.cc
@@ -18,19 +18,8 @@
 
 bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
   constexpr bool kFeatureValues[] = {
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
-    true,
+      true, true, true, true, true, true, true,
+      true, true, true, true, true, true, true,
   };
   ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
   return kFeatureValues[static_cast<int>(feature)];
@@ -38,19 +27,20 @@
 
 const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
   constexpr const char* kFeatureNames[] = {
-    "nonfunction-type-aliases",
-    "non-nullable",
-    "extension-methods",
-    "constant-update-2018",
-    "control-flow-collections",
-    "generic-metadata",
-    "set-literals",
-    "spread-collections",
-    "triple-shift",
-    "constructor-tearoffs",
-    "enhanced-enums",
-    "named-arguments-anywhere",
-    "super-parameters",
+      "nonfunction-type-aliases",
+      "non-nullable",
+      "extension-methods",
+      "constant-update-2018",
+      "control-flow-collections",
+      "generic-metadata",
+      "set-literals",
+      "spread-collections",
+      "triple-shift",
+      "constructor-tearoffs",
+      "enhanced-enums",
+      "named-arguments-anywhere",
+      "super-parameters",
+      "inference-update-1",
   };
   ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureNames));
   return kFeatureNames[static_cast<int>(feature)];
diff --git a/runtime/vm/experimental_features.h b/runtime/vm/experimental_features.h
index c32ef01..be9be59 100644
--- a/runtime/vm/experimental_features.h
+++ b/runtime/vm/experimental_features.h
@@ -27,6 +27,7 @@
   enhanced_enums,
   named_arguments_anywhere,
   super_parameters,
+  inference_update_1,
 };
 
 bool GetExperimentalFeatureDefault(ExperimentalFeature feature);
diff --git a/tests/corelib/iterable_empty_test.dart b/tests/corelib/iterable_empty_test.dart
index 7d26088..84749ce 100644
--- a/tests/corelib/iterable_empty_test.dart
+++ b/tests/corelib/iterable_empty_test.dart
@@ -18,7 +18,7 @@
     Expect.throwsRangeError(() => it.elementAt(0), name);
     Expect.throwsStateError(() => it.reduce((a, b) => a), name);
     Expect.throwsStateError(() => it.singleWhere((_) => true), name);
-    Expect.equals(42, it.fold(42, (a, b) => "not 42"), name);
+    Expect.equals(42, it.fold<dynamic>(42, (a, b) => "not 42"), name);
     Expect.equals(42, it.firstWhere((v) => true, orElse: () => 42), name);
     Expect.equals(42, it.lastWhere((v) => true, orElse: () => 42), name);
     Expect.equals("", it.join("separator"), name);
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index cea81af..dec610c 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -125,9 +125,6 @@
   macros:
     help: "Static meta-programming"
 
-  inference-update-1:
-    help: "Horizontal type inference for function expressions passed to generic invocations."
-
   inference-update-2:
     help: "Type promotion for fields"
 
@@ -264,3 +261,20 @@
       void main(){
         print(C('feature enabled').foo);
       }
+
+  inference-update-1:
+    help: "Horizontal type inference for function expressions passed to generic invocations."
+    enabledIn: '2.18.0'
+    validation: |
+      void test(List<int> list) {
+        var a = list.fold(0, (x, y) => x + y);
+        f(a);
+      }
+      void f<T>(T t) {
+        if (T == int) {
+          print('feature enabled');
+        }
+      }
+      void main() {
+        test([1, 2, 3]);
+      }