From 014ba42ab4d2fb586c53c27255878fc0927cd5e3 Mon Sep 17 00:00:00 2001 From: ASDAlexander77 Date: Tue, 27 Oct 2026 18:04:32 +0000 Subject: [PATCH] -mm=own: reverse and sort move string elements by copy reverse reads the element it swaps into a `let`, as sort's `temp` did: a `const` borrows the slot overwritten next. sort no longer assigns its optional comparator a default - a callback parameter that is assigned is one -mm=own knows nothing about, so a call of it with two elements was a use of them after a call that may release them; it gives a selectionSort helper the comparator or the default. Needs the compiler's copy of a string read out of a parameter the result borrows. Co-Authored-By: Claude Opus 5.5 --- src/generics/lib.generics.ts | 43 ++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/generics/lib.generics.ts b/src/generics/lib.generics.ts index 9656081..a7b2bf1 100644 --- a/src/generics/lib.generics.ts +++ b/src/generics/lib.generics.ts @@ -321,8 +321,10 @@ namespace __Array { const shift = this.length - 1; const size = this.length >> 1; for (let i = 0; i < size; i++) { - const v = this[i]; - this[i] = this[shift - i] + // a `let`, as sort's `temp`: under -mm=own a string element is copied out, where a + // `const` would borrow the slot overwritten next + let v = this[i]; + this[i] = this[shift - i]; this[shift - i] = v; } @@ -362,30 +364,37 @@ namespace __Array { return false; } + // The comparison is a parameter the sort only calls, never one it assigns: under -mm=own what a + // callback may release is known from the functions given for it, and a parameter assigned a + // default is one nothing knows - so a call of it with two elements would be a use of them after + // it may release them. + function selectionSort(a: T[], compare: (value1: T, value2: T) => int) { + const len = a.length; + for (let i = 0; i < len - 1; ++i) { + for (let j = i + 1; j < len; ++j) { + if (compare(a[i], a[j]) > 0) { + let temp: T = a[i]; + a[i] = a[j]; + a[j] = temp; + } + } + } + } + function sort(this: T[], callbackfn?: (value1: T, value2: T) => int): T[] { if (this.length <= 0) { return this; } - if (!callbackfn) { - callbackfn = (a, b) => { + if (callbackfn) { + selectionSort(this, callbackfn); + } else { + selectionSort(this, (a: T, b: T) => { const sa = a; const sb = b; if (sa == sb) return 0; return sa > sb ? 1 : -1; - }; - } - - const len = this.length; - // simple selection sort. - for (let i = 0; i < len - 1; ++i) { - for (let j = i + 1; j < len; ++j) { - if (callbackfn(this[i], this[j]) > 0) { - let temp: T = this[i]; - this[i] = this[j]; - this[j] = temp; - } - } + }); } return this;