Version 2.17.0-61.0.dev

Merge commit '6c10e05ba339aa4da4fc38e19fc21b450080b9cb' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 4d4da53..7659c35 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -135,12 +135,16 @@
   }
 
   /// Add constructor suggestions for the given class.
-  void _addConstructorSuggestions(ClassElement classElem) {
-    for (var constructor in classElem.constructors) {
+  void _addConstructorSuggestions(ClassElement element) {
+    if (element.isEnum) {
+      return;
+    }
+
+    for (var constructor in element.constructors) {
       if (constructor.isPrivate) {
         continue;
       }
-      if (classElem.isAbstract && !constructor.isFactory) {
+      if (element.isAbstract && !constructor.isFactory) {
         continue;
       }
       builder.suggestConstructor(constructor, kind: kind, prefix: prefix);
diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart
index a12950d..52c2abf 100644
--- a/pkg/analysis_server/test/client/completion_driver_test.dart
+++ b/pkg/analysis_server/test/client/completion_driver_test.dart
@@ -10,6 +10,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../services/completion/dart/completion_check.dart';
 import '../services/completion/dart/completion_contributor_util.dart';
 import 'impl/completion_driver.dart';
 
@@ -123,6 +124,21 @@
     return suggestions;
   }
 
+  /// TODO(scheglov) Use it everywhere instead of [addTestFile].
+  Future<CompletionResponseForTesting> getTestCodeSuggestions(
+    String content,
+  ) async {
+    await addTestFile(content);
+
+    return CompletionResponseForTesting(
+      requestOffset: driver.completionOffset,
+      replacementOffset: driver.replacementOffset,
+      replacementLength: driver.replacementLength,
+      isIncomplete: false, // TODO(scheglov) not correct
+      suggestions: suggestions,
+    );
+  }
+
   /// Display sorted suggestions.
   void printSuggestions() {
     suggestions.sort(completionComparator);
diff --git a/pkg/analysis_server/test/client/impl/completion_driver.dart b/pkg/analysis_server/test/client/impl/completion_driver.dart
index 66720b9..4907915 100644
--- a/pkg/analysis_server/test/client/impl/completion_driver.dart
+++ b/pkg/analysis_server/test/client/impl/completion_driver.dart
@@ -141,6 +141,8 @@
     ).toRequest('0');
     var response = await waitResponse(request);
     var result = CompletionGetSuggestions2Result.fromResponse(response);
+    replacementOffset = result.replacementOffset;
+    replacementLength = result.replacementLength;
     return result.suggestions;
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart
new file mode 100644
index 0000000..842ac90
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/enum_test.dart
@@ -0,0 +1,87 @@
+// 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_utilities/check/check.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../client/completion_driver_test.dart';
+import '../completion_check.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(EnumTest1);
+    defineReflectiveTests(EnumTest2);
+  });
+}
+
+@reflectiveTest
+class EnumTest1 extends AbstractCompletionDriverTest with EnumTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version1;
+}
+
+@reflectiveTest
+class EnumTest2 extends AbstractCompletionDriverTest with EnumTestCases {
+  @override
+  TestingCompletionProtocol get protocol => TestingCompletionProtocol.version2;
+}
+
+mixin EnumTestCases on AbstractCompletionDriverTest {
+  @override
+  bool get supportsAvailableSuggestions => true;
+
+  Future<void> test_unprefixed_imported() async {
+    await addProjectFile('lib/a.dart', r'''
+enum MyEnum { v }
+''');
+
+    var response = await getTestCodeSuggestions('''
+import 'a.dart';
+
+void f() {
+  ^
+}
+''');
+
+    _checkUnprefixed(response);
+  }
+
+  Future<void> test_unprefixed_local() async {
+    var response = await getTestCodeSuggestions('''
+enum MyEnum { v }
+
+void f() {
+  ^
+}
+''');
+
+    _checkUnprefixed(response);
+  }
+
+  Future<void> test_unprefixed_notImported() async {
+    await addProjectFile('lib/a.dart', r'''
+enum MyEnum { v }
+''');
+
+    var response = await getTestCodeSuggestions('''
+void f() {
+  ^
+}
+''');
+
+    _checkUnprefixed(response);
+  }
+
+  void _checkUnprefixed(CompletionResponseForTesting response) {
+    check(response).suggestions
+      ..includesAll([
+        (suggestion) => suggestion.completion.isEqualTo('MyEnum.v'),
+      ])
+      ..excludesAll([
+        (suggestion) => suggestion
+          ..completion.startsWith('MyEnum')
+          ..isConstructorInvocation,
+      ]);
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
new file mode 100644
index 0000000..b1de9ef
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
@@ -0,0 +1,14 @@
+// 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'enum_test.dart' as enum_;
+
+/// Tests suggestions produced for various kinds of declarations.
+void main() {
+  defineReflectiveSuite(() {
+    enum_.main();
+  });
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
index 8577738..0254e45 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/bool_assignment_test.dart
@@ -10,7 +10,7 @@
 
 void main() {
   defineReflectiveSuite(() {
-    // defineReflectiveTests(BoolAssignmentTest1);
+    defineReflectiveTests(BoolAssignmentTest1);
     defineReflectiveTests(BoolAssignmentTest2);
   });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index 384422b..0ed0678 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -8,6 +8,7 @@
 import 'closure_contributor_test.dart' as closure_contributor;
 import 'combinator_contributor_test.dart' as combinator_test;
 import 'completion_manager_test.dart' as completion_manager;
+import 'declaration/test_all.dart' as declaration;
 import 'extension_member_contributor_test.dart' as extension_member_contributor;
 import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
 import 'imported_reference_contributor_test.dart' as imported_ref_test;
@@ -32,6 +33,7 @@
     closure_contributor.main();
     combinator_test.main();
     completion_manager.main();
+    declaration.main();
     extension_member_contributor.main();
     field_formal_contributor_test.main();
     imported_ref_test.main();
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index d3dc572..edeba68 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -8431,35 +8431,38 @@
 
   /**
    * 12.1 Constants: A constant expression is ... a constant list literal.
+   *
+   * Note: This diagnostic is never displayed to the user, so it doesn't need
+   * to be documented.
    */
   static const CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL =
       CompileTimeErrorCode(
     'MISSING_CONST_IN_LIST_LITERAL',
-    "List literals must be prefixed with 'const' when used as a constant "
-        "expression.",
-    correctionMessage: "Try adding the keyword 'const' before the literal.",
+    "Seeing this message constitutes a bug. Please report it.",
   );
 
   /**
    * 12.1 Constants: A constant expression is ... a constant map literal.
+   *
+   * Note: This diagnostic is never displayed to the user, so it doesn't need
+   * to be documented.
    */
   static const CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL =
       CompileTimeErrorCode(
     'MISSING_CONST_IN_MAP_LITERAL',
-    "Map literals must be prefixed with 'const' when used as a constant "
-        "expression.",
-    correctionMessage: "Try adding the keyword 'const' before the literal.",
+    "Seeing this message constitutes a bug. Please report it.",
   );
 
   /**
    * 12.1 Constants: A constant expression is ... a constant set literal.
+   *
+   * Note: This diagnostic is never displayed to the user, so it doesn't need
+   * to be documented.
    */
   static const CompileTimeErrorCode MISSING_CONST_IN_SET_LITERAL =
       CompileTimeErrorCode(
     'MISSING_CONST_IN_SET_LITERAL',
-    "Set literals must be prefixed with 'const' when used as a constant "
-        "expression.",
-    correctionMessage: "Try adding the keyword 'const' before the literal.",
+    "Seeing this message constitutes a bug. Please report it.",
   );
 
   /**
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index f3dcc6d..d791d4c 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -7304,17 +7304,26 @@
       var m = <String, int>{'a' : 2};
       ```
   MISSING_CONST_IN_LIST_LITERAL:
-    problemMessage: "List literals must be prefixed with 'const' when used as a constant expression."
-    correctionMessage: "Try adding the keyword 'const' before the literal."
-    comment: "12.1 Constants: A constant expression is ... a constant list literal."
+    problemMessage: Seeing this message constitutes a bug. Please report it.
+    comment: |-
+      12.1 Constants: A constant expression is ... a constant list literal.
+      
+      Note: This diagnostic is never displayed to the user, so it doesn't need
+      to be documented.
   MISSING_CONST_IN_MAP_LITERAL:
-    problemMessage: "Map literals must be prefixed with 'const' when used as a constant expression."
-    correctionMessage: "Try adding the keyword 'const' before the literal."
-    comment: "12.1 Constants: A constant expression is ... a constant map literal."
+    problemMessage: Seeing this message constitutes a bug. Please report it.
+    comment: |-
+      12.1 Constants: A constant expression is ... a constant map literal.
+
+      Note: This diagnostic is never displayed to the user, so it doesn't need
+      to be documented.
   MISSING_CONST_IN_SET_LITERAL:
-    problemMessage: "Set literals must be prefixed with 'const' when used as a constant expression."
-    correctionMessage: "Try adding the keyword 'const' before the literal."
-    comment: "12.1 Constants: A constant expression is ... a constant set literal."
+    problemMessage: Seeing this message constitutes a bug. Please report it.
+    comment: |-
+      12.1 Constants: A constant expression is ... a constant set literal.
+
+      Note: This diagnostic is never displayed to the user, so it doesn't need
+      to be documented.
   MISSING_DART_LIBRARY:
     problemMessage: "Required library '{0}' is missing."
     correctionMessage: Re-install the Dart or Flutter SDK.
diff --git a/runtime/tests/vm/dart/splay_test.dart b/runtime/tests/vm/dart/splay_test.dart
index 7e974a1..1abb197 100644
--- a/runtime/tests/vm/dart/splay_test.dart
+++ b/runtime/tests/vm/dart/splay_test.dart
@@ -27,6 +27,7 @@
 // VMOptions=--verify_store_buffer
 // VMOptions=--stress_write_barrier_elimination
 // VMOptions=--old_gen_heap_size=100
+// VMOptions=--mark_when_idle
 
 import "dart:math";
 import 'package:benchmark_harness/benchmark_harness.dart';
diff --git a/runtime/tests/vm/dart_2/splay_test.dart b/runtime/tests/vm/dart_2/splay_test.dart
index a793419..f1b401e 100644
--- a/runtime/tests/vm/dart_2/splay_test.dart
+++ b/runtime/tests/vm/dart_2/splay_test.dart
@@ -31,6 +31,7 @@
 // VMOptions=--verify_store_buffer
 // VMOptions=--stress_write_barrier_elimination
 // VMOptions=--old_gen_heap_size=100
+// VMOptions=--mark_when_idle
 
 import "dart:math";
 import 'package:benchmark_harness/benchmark_harness.dart';
diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc
index b10e2d7..244a95e 100644
--- a/runtime/vm/compiler/backend/il_riscv.cc
+++ b/runtime/vm/compiler/backend/il_riscv.cc
@@ -4027,7 +4027,7 @@
       }
       __ SmiUntag(TMP2, left);
       __ srl(TMP, TMP2, TMP);
-      __ SmiTag(result);
+      __ SmiTag(result, TMP);
       if (deopt != nullptr) {
         __ SmiUntag(TMP2, result);
         __ bne(TMP, TMP2, deopt);
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 3e0ea0f..b5cde40 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -140,6 +140,9 @@
   P(scavenger_tasks, int, 2,                                                   \
     "The number of tasks to spawn during scavenging (0 means "                 \
     "perform all marking on main thread).")                                    \
+  P(mark_when_idle, bool, false,                                               \
+    "The Dart thread will assist in concurrent marking during idle time and "  \
+    "is counted as one marker task")                                           \
   P(marker_tasks, int, 2,                                                      \
     "The number of tasks to spawn during old gen GC marking (0 means "         \
     "perform all marking on main thread).")                                    \
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index b226659..286206f 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -243,6 +243,7 @@
 #endif
     while ((old_space_->tasks() > 0) ||
            (old_space_->phase() != PageSpace::kDone)) {
+      old_space_->AssistTasks(&ml);
       if (old_space_->phase() == PageSpace::kAwaitingFinalization) {
         ml.Exit();
         heap_->CollectOldSpaceGarbage(thread, GCType::kMarkSweep,
@@ -408,6 +409,8 @@
     }
   }
 
+  old_space_.NotifyIdle(deadline);
+
   if (OS::GetCurrentMonotonicMicros() < deadline) {
     SemiSpace::DrainCache();
   }
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 43b4c62..adbaab4 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -78,15 +78,37 @@
   }
 
   void DrainMarkingStack() {
+    while (ProcessMarkingStack()) {
+    }
+  }
+
+  void ProcessMarkingStackUntil(int64_t deadline) {
+    // We check the clock *before* starting a batch of work, but we want to
+    // *end* work before the deadline. So we compare to the deadline adjusted
+    // by a conservative estimate of the duration of one batch of work.
+    deadline -= 1500;
+
+    while ((OS::GetCurrentMonotonicMicros() < deadline) &&
+           ProcessMarkingStack()) {
+    }
+  }
+
+  bool ProcessMarkingStack() {
     ObjectPtr raw_obj = work_list_.Pop();
     if ((raw_obj == nullptr) && ProcessPendingWeakProperties()) {
       raw_obj = work_list_.Pop();
     }
 
     if (raw_obj == nullptr) {
-      return;
+      return false;  // No more work.
     }
 
+    // A 512kB budget is choosen to be large enough that we don't waste too much
+    // time on the overhead of exiting this function, querying the clock, and
+    // re-entering, and small enough that a few batches can fit in the idle time
+    // between animation frames. This amount of marking takes ~1ms on a Pixel
+    // phone.
+    intptr_t remaining_budget = 512 * KB;
     do {
       do {
         // First drain the marking stacks.
@@ -100,6 +122,10 @@
           size = ProcessWeakProperty(raw_weak, /* did_mark */ true);
         }
         marked_bytes_ += size;
+        remaining_budget -= size;
+        if (remaining_budget < 0) {
+          return true;  // More to mark.
+        }
 
         raw_obj = work_list_.Pop();
       } while (raw_obj != nullptr);
@@ -111,6 +137,8 @@
       // by the handling of weak properties.
       raw_obj = work_list_.Pop();
     } while (raw_obj != nullptr);
+
+    return false;  // No more work.
   }
 
   // Races: The concurrent marker is racing with the mutator, but this race is
@@ -767,6 +795,9 @@
                                            &deferred_marking_stack_);
 
   const intptr_t num_tasks = FLAG_marker_tasks;
+  RELEASE_ASSERT(num_tasks >= 1);
+  const intptr_t num_concurrent_tasks =
+      num_tasks - (FLAG_mark_when_idle ? 1 : 0);
 
   {
     // Bulk increase task count before starting any task, instead of
@@ -775,9 +806,9 @@
     MonitorLocker ml(page_space->tasks_lock());
     ASSERT(page_space->phase() == PageSpace::kDone);
     page_space->set_phase(PageSpace::kMarking);
-    page_space->set_tasks(page_space->tasks() + num_tasks);
+    page_space->set_tasks(page_space->tasks() + num_concurrent_tasks);
     page_space->set_concurrent_marker_tasks(
-        page_space->concurrent_marker_tasks() + num_tasks);
+        page_space->concurrent_marker_tasks() + num_concurrent_tasks);
   }
 
   ResetSlices();
@@ -793,7 +824,7 @@
           this, isolate_group_, page_space, visitor);
       ASSERT(result);
     } else {
-      // Last worker is the main thread, which will only mark roots.
+      // For the last visitor, mark roots on the main thread.
       TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ConcurrentMark");
       int64_t start = OS::GetCurrentMonotonicMicros();
       IterateRoots(visitor);
@@ -803,10 +834,16 @@
         THR_Print("Task marked %" Pd " bytes in %" Pd64 " micros.\n",
                   visitor->marked_bytes(), visitor->marked_micros());
       }
-      // Continue non-root marking concurrently.
-      bool result = Dart::thread_pool()->Run<ConcurrentMarkTask>(
-          this, isolate_group_, page_space, visitor);
-      ASSERT(result);
+      if (FLAG_mark_when_idle) {
+        // Not spawning a thread to continue processing with the last visitor.
+        // This visitor is instead left available for the main thread to
+        // contribute to marking during idle time.
+      } else {
+        // Continue non-root marking concurrently.
+        bool result = Dart::thread_pool()->Run<ConcurrentMarkTask>(
+            this, isolate_group_, page_space, visitor);
+        ASSERT(result);
+      }
     }
   }
 
@@ -819,6 +856,31 @@
   }
 }
 
+void GCMarker::AssistConcurrentMark() {
+  if (!FLAG_mark_when_idle) return;
+
+  SyncMarkingVisitor* visitor = visitors_[FLAG_marker_tasks - 1];
+  ASSERT(visitor != nullptr);
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "Mark");
+  int64_t start = OS::GetCurrentMonotonicMicros();
+  visitor->DrainMarkingStack();
+  int64_t stop = OS::GetCurrentMonotonicMicros();
+  visitor->AddMicros(stop - start);
+}
+
+void GCMarker::NotifyIdle(int64_t deadline) {
+  if (!FLAG_mark_when_idle) return;
+
+  SyncMarkingVisitor* visitor = visitors_[FLAG_marker_tasks - 1];
+  if (visitor == nullptr) return;
+
+  TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "IncrementalMark");
+  int64_t start = OS::GetCurrentMonotonicMicros();
+  visitor->ProcessMarkingStackUntil(deadline);
+  int64_t stop = OS::GetCurrentMonotonicMicros();
+  visitor->AddMicros(stop - start);
+}
+
 void GCMarker::MarkObjects(PageSpace* page_space) {
   if (isolate_group_->marking_stack() != NULL) {
     isolate_group_->DisableIncrementalBarrier();
diff --git a/runtime/vm/heap/marker.h b/runtime/vm/heap/marker.h
index 2fde0d8..ec36170 100644
--- a/runtime/vm/heap/marker.h
+++ b/runtime/vm/heap/marker.h
@@ -38,6 +38,13 @@
   // Marking must later be finalized by calling MarkObjects.
   void StartConcurrentMark(PageSpace* page_space);
 
+  // Called when a synchronous GC is required, but concurrent marking is still
+  // in progress.
+  void AssistConcurrentMark();
+
+  // Perform incremental marking if available.
+  void NotifyIdle(int64_t deadline);
+
   // (Re)mark roots, drain the marking queue and finalize weak references.
   // Does not required StartConcurrentMark to have been previously called.
   void MarkObjects(PageSpace* page_space);
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index f10cdd7..440bcd0 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -1036,6 +1036,20 @@
   return estimated_mark_compact_completion <= deadline;
 }
 
+void PageSpace::NotifyIdle(int64_t deadline) {
+  if (marker_ != nullptr) {
+    marker_->NotifyIdle(deadline);
+  }
+}
+
+void PageSpace::AssistTasks(MonitorLocker* ml) {
+  if (phase() == PageSpace::kMarking) {
+    ml->Exit();
+    marker_->AssistConcurrentMark();
+    ml->Enter();
+  }
+}
+
 void PageSpace::TryReleaseReservation() {
   ASSERT(phase() != kSweepingLarge);
   ASSERT(phase() != kSweepingRegular);
@@ -1107,6 +1121,7 @@
       return;
     }
 
+    AssistTasks(&locker);
     while (tasks() > 0) {
       locker.Wait();
     }
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 11a4cc2..5a3c5c0 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -434,6 +434,8 @@
 
   bool ShouldStartIdleMarkSweep(int64_t deadline);
   bool ShouldPerformIdleMarkCompact(int64_t deadline);
+  void NotifyIdle(int64_t deadline);
+  void AssistTasks(MonitorLocker* ml);
 
   void AddGCTime(int64_t micros) { gc_time_micros_ += micros; }
 
diff --git a/tests/language/vm/fuzzer_unsigned_shift_right_test.dart b/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
new file mode 100644
index 0000000..01e935a
--- /dev/null
+++ b/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+/// VMOptions=--deterministic
+
+// The Dart Project Fuzz Tester (1.93).
+// Program generated as:
+//   dart dartfuzz.dart --seed 316265767 --no-fp --no-ffi --flat
+
+import 'dart:typed_data';
+
+Int16List? foo0_0(int par4) {
+  if (par4 >= 36) {
+    return Int16List(40);
+  }
+  for (int loc0 = 0; loc0 < 31; loc0++) {
+    for (int loc1 in ((Uint8ClampedList.fromList(Uint8List(26)))
+        .sublist((11 >>> loc0), null))) {}
+  }
+  return foo0_0(par4 + 1);
+}
+
+main() {
+  foo0_0(0);
+}
diff --git a/tools/VERSION b/tools/VERSION
index 206390c..020f99a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 60
+PRERELEASE 61
 PRERELEASE_PATCH 0
\ No newline at end of file