From 223033de5e253bc9afe173097a6f7bdf934c2c26 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 1 Nov 2023 23:24:14 +0000 Subject: [PATCH] Avoid setRange with potentially incompatible types Fixes #317 --- CHANGELOG.md | 2 ++ lib/src/algorithms.dart | 5 +++-- test/algorithms_test.dart | 9 +++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c27f014f..df89964f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ - Adds `shuffled` to `IterableExtension`. - Shuffle `IterableExtension.sample` results. +- Fix `mergeSort` when the runtime iterable generic is a subtype of the static + generic. ## 1.18.0 diff --git a/lib/src/algorithms.dart b/lib/src/algorithms.dart index 5833bbd1..e551dad1 100644 --- a/lib/src/algorithms.dart +++ b/lib/src/algorithms.dart @@ -394,8 +394,9 @@ void _merge( } // First list empties first. Reached by break above. target[targetOffset++] = secondElement; - target.setRange( - targetOffset, targetOffset + (secondEnd - cursor2), secondList, cursor2); + for (var i = targetOffset; i < targetOffset + (secondEnd - cursor2); i++) { + target[i] = secondList[(i - targetOffset) + cursor2]; + } } /// Sort [elements] using a quick-sort algorithm. diff --git a/test/algorithms_test.dart b/test/algorithms_test.dart index c2ffb7f2..009f6a0a 100644 --- a/test/algorithms_test.dart +++ b/test/algorithms_test.dart @@ -366,6 +366,15 @@ void main() { reverse(l, 0, 6); expect(l, equals([2, 1, 4, 3, 6, 5])); }); + + test('mergeSort works when runtime generic is a subtype of the static type', + () { + // Regression test for https://github.com/dart-lang/collection/issues/317 + final length = 32; // _mergeSortLimit + // In order list, first half empties first during merge. + final list = List.generate(length, (i) => i); + expect(() => mergeSort(list), returnsNormally); + }); } class C {