diff --git a/.roc-version b/.roc-version index eb9725b..80bf11e 100644 --- a/.roc-version +++ b/.roc-version @@ -1 +1 @@ -nightly-2026-09-16-a49a16f +nightly-2026-10-01-a932c65 diff --git a/examples/CliArgs.roc b/examples/CliArgs.roc index 158d965..e9cdbea 100644 --- a/examples/CliArgs.roc +++ b/examples/CliArgs.roc @@ -21,7 +21,7 @@ CliArgs := [].{ ## Decode argv for an application and report malformed native text as a usage ## error. Applications can then keep their domain logic entirely in Str. - to_strs! : List(OsStr) => Try(List(Str), [Exit(I32), StderrErr(IOErr), ..]) + to_strs! : List(OsStr) => Try(List(Str), [Exit(I32), StderrErr(IOErr)]) to_strs! = |os_args| match decode(os_args) { Ok(args) => Ok(args) diff --git a/examples/bidi-analysis.roc b/examples/bidi-analysis.roc index 6e89bae..0058e46 100644 --- a/examples/bidi-analysis.roc +++ b/examples/bidi-analysis.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -67,11 +67,11 @@ render = |base, analysis, line| { \\mirrored-glyphs: ${format_mirrors(Bidi.line_mirroring(line))} } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? match args { - [_app, base_text, source] => { + [base_text, source] => { base = match parse_base(base_text) { Ok(value) => value Err(UnknownBase(name)) => { diff --git a/examples/count-scalars.roc b/examples/count-scalars.roc index 4572078..ff4b683 100644 --- a/examples/count-scalars.roc +++ b/examples/count-scalars.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -57,12 +57,12 @@ expect scalar_summary("aé🦘").positions == [ "2: value=129432 bytes=3..7", ] -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? text = match args { - [_app] => default_text - [_app, provided] => provided + [] => default_text + [provided] => provided _ => { Stderr.line!("usage: count-scalars [TEXT]")? return Err(Exit(2)) diff --git a/examples/decode-utf8-stream.roc b/examples/decode-utf8-stream.roc index d035388..72f701c 100644 --- a/examples/decode-utf8-stream.roc +++ b/examples/decode-utf8-stream.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -163,10 +163,10 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? - chunks = args.drop_first(1) + chunks = args if chunks.is_empty() { Stderr.line!("usage: decode-utf8-stream HEX_BYTES [HEX_BYTES ...]")? Stderr.line!(" bytes are comma-separated; use - for an empty chunk")? diff --git a/examples/encode-code-points.roc b/examples/encode-code-points.roc index c6f65f7..bf0855a 100644 --- a/examples/encode-code-points.roc +++ b/examples/encode-code-points.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -62,11 +62,10 @@ expect encode(["D800"], 4) == Err(Surrogate("D800")) expect encode(["110000"], 4) == Err(OutOfRange("110000")) expect encode(["1F998"], 3) == Err(LimitExceeded({ limit: 3, required: 4 })) -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? - user_args = args.drop_first(1) - (limit_text, tokens) = match user_args { + (limit_text, tokens) = match args { [limit_arg, first, .. as rest] => (limit_arg, [first].concat(rest)) _ => { Stderr.line!("usage: encode-code-points MAX_OUTPUT_BYTES HEX_CODE_POINT [HEX_CODE_POINT ...]")? diff --git a/examples/estimate-eaw-cells.roc b/examples/estimate-eaw-cells.roc index db35bea..ee7e8f7 100644 --- a/examples/estimate-eaw-cells.roc +++ b/examples/estimate-eaw-cells.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", # Use a release bundle URL in applications. The end-to-end suite rewrites # this local development dependency to the bundle served by the test driver. unicode: "../package/main.roc", @@ -48,12 +48,12 @@ expect measure_cells("δΈ–η•Œ") == { cells: 4, scalars: 2 } expect measure_cells("οΌ‘A") == { cells: 3, scalars: 2 } expect measure_cells("é") == { cells: 2, scalars: 2 } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? text = match args { - [_app] => default_text - [_app, provided] => provided + [] => default_text + [provided] => provided _ => { Stderr.line!("usage: estimate-eaw-cells [TEXT]")? return Err(Exit(2)) diff --git a/examples/font-script-runs.roc b/examples/font-script-runs.roc index 30d01f7..7becdc9 100644 --- a/examples/font-script-runs.roc +++ b/examples/font-script-runs.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -114,12 +114,12 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? request = match args { - [_app, "complete", preferences, source] => Complete({ preferences, source }) - [_app, "chunks", max_pending, preferences, first, .. as rest] => { + ["complete", preferences, source] => Complete({ preferences, source }) + ["chunks", max_pending, preferences, first, .. as rest] => { Chunks({ max_pending, preferences, chunks: [first].concat(rest) }) } _ => { diff --git a/examples/limit-display-name.roc b/examples/limit-display-name.roc index bbbc794..e6353b0 100644 --- a/examples/limit-display-name.roc +++ b/examples/limit-display-name.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -48,11 +48,11 @@ expect limit_display_name("éclair", 1) == Ok({ slice: "é", truncated: Bool.T expect limit_display_name("πŸ‘©πŸ½β€πŸš€ mission", 1) == Ok({ slice: "πŸ‘©πŸ½β€πŸš€", truncated: Bool.True }) expect limit_display_name("πŸ‡¦πŸ‡Ί team", 1) == Ok({ slice: "πŸ‡¦πŸ‡Ί", truncated: Bool.True }) -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? (limit_text, source) = match args { - [_app, limit_arg, display_name] => (limit_arg, display_name) + [limit_arg, display_name] => (limit_arg, display_name) _ => { Stderr.line!("usage: limit-display-name MAX_GRAPHEMES DISPLAY_NAME")? return Err(Exit(2)) diff --git a/examples/line-break-opportunities.roc b/examples/line-break-opportunities.roc index 5357842..6ed4df1 100644 --- a/examples/line-break-opportunities.roc +++ b/examples/line-break-opportunities.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -108,12 +108,12 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? request = match args { - [_app, "complete", profile_text, source] => Complete({ profile_text, source }) - [_app, "chunks", profile_text, first, .. as rest] => Chunks({ profile_text, chunks: [first].concat(rest) }) + ["complete", profile_text, source] => Complete({ profile_text, source }) + ["chunks", profile_text, first, .. as rest] => Chunks({ profile_text, chunks: [first].concat(rest) }) _ => { Stderr.line!("usage: line-break-opportunities complete PROFILE TEXT")? Stderr.line!(" line-break-opportunities chunks PROFILE CHUNK [CHUNK ...]")? diff --git a/examples/shaping-facts.roc b/examples/shaping-facts.roc index bfbd07a..13c7282 100644 --- a/examples/shaping-facts.roc +++ b/examples/shaping-facts.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -140,11 +140,11 @@ expect { and Emoji.variation_presentation(letter, vs16) == None } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? source = match args { - [_app, text] => text + [text] => text _ => { Stderr.line!("usage: shaping-facts TEXT")? return Err(Exit(2)) diff --git a/examples/split-graphemes.roc b/examples/split-graphemes.roc index 0507e20..7207617 100644 --- a/examples/split-graphemes.roc +++ b/examples/split-graphemes.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -58,12 +58,12 @@ expect segment("πŸ‡¦πŸ‡ΊπŸ¦˜") == [ ] expect Grapheme.slices("πŸ‘©β€πŸš€") == ["πŸ‘©β€πŸš€"] -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? source = match args { - [_app] => default_text - [_app, provided] => provided + [] => default_text + [provided] => provided _ => { Stderr.line!("usage: split-graphemes [TEXT]")? return Err(Exit(2)) diff --git a/examples/stream-grapheme-ranges.roc b/examples/stream-grapheme-ranges.roc index bb41ba0..b2bcf97 100644 --- a/examples/stream-grapheme-ranges.roc +++ b/examples/stream-grapheme-ranges.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -88,10 +88,10 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? - chunks = args.drop_first(1) + chunks = args if chunks.is_empty() { Stderr.line!("usage: stream-grapheme-ranges CHUNK [CHUNK ...]")? Stderr.line!(" chunks must be scalar-aligned; use - for an empty chunk")? diff --git a/package/Bidi.roc b/package/Bidi.roc index f837b14..f8eedf1 100644 --- a/package/Bidi.roc +++ b/package/Bidi.roc @@ -288,7 +288,6 @@ range_from_offsets = |byte_start, byte_end, scalar_start, scalar_end| { } is_p1_range = |source, selected| { - ## This deliberately does not call `p1_ranges`: range analysis must not ## allocate one result per preceding paragraph just to validate `selected`. ## A pending CR delays commitment until the next scalar determines whether diff --git a/package/InternalCase.roc b/package/InternalCase.roc index 28a59a8..0724672 100644 --- a/package/InternalCase.roc +++ b/package/InternalCase.roc @@ -528,7 +528,6 @@ mapping_shape = |mapping, input| match mapping { append_mapping = |initial, mapping| { for_mapping(mapping, initial, |bytes, scalar| append_utf8(bytes, scalar)) - } for_mapping = |mapping, initial, emit| match mapping { diff --git a/tests/apps/bidi/main.roc b/tests/apps/bidi/main.roc index 3c187bc..5bd852c 100644 --- a/tests/apps/bidi/main.roc +++ b/tests/apps/bidi/main.roc @@ -125,7 +125,7 @@ verify_metamorphic_invariants = |protocol_input| { } plain = bidi_result(Bidi.analyze_paragraph("אa${empty_input}", Auto, Bidi.default_limits))? - isolated = bidi_result(Bidi.analyze_paragraph("א⁨a⁩a${empty_input}", Auto, Bidi.default_limits))? + isolated = bidi_result(Bidi.analyze_paragraph("א\u(2068)a\u(2069)a${empty_input}", Auto, Bidi.default_limits))? plain_first = Bidi.entries(plain).get(0) ?? return Err("missing plain first scalar") plain_last = Bidi.entries(plain).get(1) ?? return Err("missing plain last scalar") isolated_first = Bidi.entries(isolated).get(0) ?? return Err("missing isolate first scalar") @@ -208,13 +208,13 @@ verify_mapping_inverse = |visual_to_logical, logical_to_visual, line_start| { verify_control_and_bracket_boundaries : Str -> Try({}, Str) verify_control_and_bracket_boundaries = |protocol_input| { empty_input = protocol_input.drop_last_bytes(protocol_input.count_utf8_bytes()) ?? return Err("could not derive empty protocol input") - controls = Str.join_with([repeat_text("‫", 126), "a", repeat_text("‬", 126), empty_input], "") + controls = Str.join_with([repeat_text("\u(202B)", 126), "a", repeat_text("\u(202C)", 126), empty_input], "") control_analysis = bidi_result(Bidi.analyze_paragraph(controls, Auto, Bidi.default_limits))? verify_level_parity(Bidi.levels(control_analysis))? if !contains_level(Bidi.levels(control_analysis), 126) { return Err("deep explicit controls did not reach the permitted I2 level 126") } - missing_pdi = bidi_result(Bidi.analyze_paragraph("⁨א⁨a${empty_input}", Auto, Bidi.default_limits))? + missing_pdi = bidi_result(Bidi.analyze_paragraph("\u(2068)א\u(2068)a${empty_input}", Auto, Bidi.default_limits))? verify_level_parity(Bidi.levels(missing_pdi))? for depth in [62, 63] {