Repository navigation
feat(ts): translate start.. as an iterator, stepping as std's does past its type's maximum - #320
Merged
Merged
Conversation
Quest-Claim: 5288007f86eede93
…st its type's maximum Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # ts/fixtures/lang/expected/harness.ts # ts/fixtures/lang/expected/keys.ts # ts/fixtures/lang/src/harness.rs
…her end Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
marked this pull request as ready for review
October 31, 2026 02:35
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 17 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
kixelated
added a commit
that referenced
this pull request
Oct 31, 2026
#320 made start.. an rt.RangeFrom iterator while this branch removed rt.rangeClone, so RangeFrom gets its own clone() and the iterator clone mapping takes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
added a commit
that referenced
this pull request
Oct 31, 2026
* chore(quest): claim quest/m3/ts-iter-clone.md Quest-Claim: 36120e2558fbb4d9 * feat(ts): clone std's iterators and adaptors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(ts): clone a start.. as the other ranges, after merging main #320 made start.. an rt.RangeFrom iterator while this branch removed rt.rangeClone, so RangeFrom gets its own clone() and the iterator clone mapping takes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Luke Curley <432854+kixelated@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
An unbounded
start..was a plain{ start }object, so wherever an adaptor or consumer wants anrt.Iterit failedtsc:firsts.iter().zip(0..)becamert.iterZip(rt.iterSlice(firsts), { start: 0 })(keys.ts(1881,77): error TS2353: ... 'start' does not exist in type 'Iter<u8>'). The same happened forchain,flatten/flat_map,extend,collect/from_iter, and for astart..as its own receiver ((0..).take(3),r.next(),for i in a..). Acharrange of any kind also stepped straight into the surrogates.Approach
start..is nowrt.RangeFrom<T>, anrt.Iterclass, the same wayrt.Rangeis. That fixes every position at once, because the value already is an iterator. It carries its type'sStep.nextandnthcompute the nextstartbefore handing back the item, as std'sRangeFromdoes. Stepping past the type's last value panics with std's debug message: "attempt to add with overflow" for integers, "overflow inStep::forward" forchar.sizeHintis(usize::MAX, None), soVec::extend(250u8..)andVec::from_iter(250u8..)panic with "capacity overflow" up front, matching std'sTrustedLenpath.rt.charStepskips the surrogate gap in both directions.rt.Range,rt.RangeInclusive, andrt.RangeFromofchartake it, andsteps_betweensubtracts the gap.library::range_step, picks theStepfor every place a range is built: rvalues, constants, andRangeInclusive::new.keys::arraysin the lang fixture is back to the naturalfirsts.iter().zip(0..).iters::range_fromsruns against native wasm32 (a debug build, like the fixture), plus 2,560 named inputs incaller.ts. It covers:char, starting 0 to 3 below the maximum;nextand byfor_each. std'sTrustedLenzip fold reads one item fewer thannextdoes when the range comes first;u64past 2^53 andu128past 2^64;Range,RangeInclusive, andRangeFromofcharacross the surrogates and up tochar::MAX;chain,extend,flatten/flat_mapofstart..,a..b, anda..=b;BTreeMapcollected fromzip(0..),Vec::from_iter,String::from_iter,step_by,nth,by_ref, andforwithbreak;TrustedLenzip fold gives 107 inrange_fromsalone, and leavingcharStepunsaturated gives 19.Impact
start..is typedrt.RangeFrom<T>, not{ start: T }. A caller passing one to a translated function buildsnew rt.RangeFrom(start, rt.<int>Step)(MIGRATE.md). Bindings that take one still readstart, because the class instance still has that field.rt.Rangeandrt.RangeInclusiveofchartakert.charStep.rt.RangeFromandrt.charStep.rt.charStepsaturates atchar::MAXand'\0', as std'schar::forward_overflowingandbackward_overflowingdo, so an exhaustedcharrange's bounds read as std's.just ts moq). Its output uses nostart.., so it is unchanged. The lang fixture'skeys::arraysis the consumer that found the bug.Alternatives
{ start }and wrap it at each iterator position. Rejected: receivers ((0..).take(3),r.next(),&mutborrows) would each need their own wrapping, plus a write-back to the original range.overflow-checks = falseand wrap the way a release build does. Not modeled: translation always lowers std's overflow asserts as panics, as for every otherrustc_inherit_overflow_checksfunction, and the fixture is built in debug.Choices made without asking
Iterator::eq,ne,lt,le,gt,ge,cmp, andpartial_cmprefuse for every iterator today, not only ranges. They went into a follow-up quest instead of this PR.RangeFrom'sClone,==, andcontains, andis_empty/containsof acharrange, were unsupported before this PR and still are. Clone is folded into the existingts-iter-clonequest.Follow-ups
/quest/m3/ts-iter-clone.mdnow namesstart...Review
Codex
gpt-6.1-solat medium effort, viaquest review --base origin/main. Reviewed head: f553320.charStepreturned an invalidcharon overflow, while std saturates atchar::MAXand'\0'. Fixed in f553320, with a differential test that reads the bounds after exhaustion.mir/mod.rs. Refuted: the branch was behind origin/main, so the review diff showed fix(ts): mark a parameter unused when its function's output never reads it #318 as removed. Merging origin/main in d3e5dd7 brought it back.Local checks:
just ciinsidenix developpassed on f553320.just ts moqpassed on 0540c60, and this fix touches onlycharstepping, which moq-net's output doesn't use.🤖 Generated with Claude Code
(written by Claude Opus 5.5)