From ca4a68ab44b843286926ddd71abf7cb1d5a2693c Mon Sep 17 00:00:00 2001 From: Karakatiza666 Date: Mon, 31 Aug 2026 09:41:45 +0400 Subject: [PATCH 1/2] Look column names up by name, not by static dispatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `lookup_value!` found a column with `cols.find_first_index(...)`. The decoder combinators are deliberately unannotated, so at that point the compiler has not worked out what `cols` is, and asking for a method on it leaves a question the compiler has to carry into whatever decoder an application writes. There it still cannot be answered. Since roc-lang/roc#10984 those questions no longer share an answer between calls, so a decoder with a name of its own decode_todo = |cols| |stmt| { id = Sqlite.i64("id")(cols)(stmt)? task = Sqlite.str("task")(cols)(stmt)? status = Sqlite.str("status")(cols)(stmt)? ... asks about `cols` three separate times and gets nowhere: ── ✗ missing method ─ examples/sqlite-basic.roc:65:8 This is trying to dispatch a method named find_first_index on an unresolved type variable, but unresolved type variables have no methods. Naming the builtin says which type the lookup comes from, which settles `cols` as a `List(Str)` here and leaves nothing for the application to resolve. This is already how Path.roc reads the same lookup. Add an expect covering a decoder with a name, which is the shape that breaks. The inline `|cols| |stmt| ...` form kept compiling and hid the regression. --- platform/Sqlite.roc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/platform/Sqlite.roc b/platform/Sqlite.roc index 4488986d..4d41098c 100644 --- a/platform/Sqlite.roc +++ b/platform/Sqlite.roc @@ -395,7 +395,7 @@ decode_rows! = |stmt, gen_decode| { } lookup_value! = |cols, stmt, name| - match cols.find_first_index(|x| x == name) { + match List.find_first_index(cols, |x| x == name) { Ok(index) => sqlite_column_value!(stmt, index) Err(NotFound) => Err(NoSuchField(name)) } @@ -499,3 +499,20 @@ code_from_i64 = |code| 101 => Done other => Unknown(other) } + +## A row decoder written the way an application writes one, with a name of its +## own. The compiler has to settle its type right here, before `query_many!` +## ever gets to say what `cols` is. Each column asks about `cols` separately, +## and since roc-lang/roc#10984 those questions no longer share an answer. +## +## The test is successful if this snippet compiles. +expect { + _decode_row = |cols| + |stmt| { + id = Sqlite.i64("id")(cols)(stmt)? + task = Sqlite.str("task")(cols)(stmt)? + status = Sqlite.str("status")(cols)(stmt)? + Ok({ id, task, status }) + } + Bool.True +} From 891cb19a81d87d63bece2c839e3f3c1e70b6b636 Mon Sep 17 00:00:00 2001 From: Karakatiza666 Date: Mon, 31 Aug 2026 09:41:45 +0400 Subject: [PATCH 2/2] Move CI to nightly-2026-08-30-34e7489 CI pinned nightly-2026-08-23-fb208ba, which is older than roc-lang/roc#10984. The inference change that broke the SQLite row decoders does not show up at that pin, so neither the bug nor the test guarding it means anything until CI moves past it. 08-30 is the newest published nightly. The platform uses no `List.sort`, so it is clear of the sort segfault that nightly also carries (roc-lang/roc#10993, fixed upstream by #11002 after 08-30 was cut). --- .github/workflows/ci.yml | 6 +++--- platform/Sqlite.roc | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f35cdd7f..27ed2da9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,7 +39,7 @@ jobs: - uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0 with: version: nightly-new-compiler - nightly-tag: nightly-2026-08-23-fb208ba + nightly-tag: nightly-2026-08-30-34e7489 - name: Install Rust toolchain run: | rustup toolchain install "${{ needs.rust-version.outputs.version }}" --profile minimal --target x86_64-unknown-linux-musl --component llvm-tools-preview @@ -58,7 +58,7 @@ jobs: - uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0 with: version: nightly-new-compiler - nightly-tag: nightly-2026-08-23-fb208ba + nightly-tag: nightly-2026-08-30-34e7489 - name: Install Rust toolchain shell: bash run: | @@ -103,7 +103,7 @@ jobs: - uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0 with: version: nightly-new-compiler - nightly-tag: nightly-2026-08-23-fb208ba + nightly-tag: nightly-2026-08-30-34e7489 - name: Install Rust toolchain shell: bash run: | diff --git a/platform/Sqlite.roc b/platform/Sqlite.roc index 4d41098c..064edf8d 100644 --- a/platform/Sqlite.roc +++ b/platform/Sqlite.roc @@ -500,10 +500,10 @@ code_from_i64 = |code| other => Unknown(other) } -## A row decoder written the way an application writes one, with a name of its -## own. The compiler has to settle its type right here, before `query_many!` -## ever gets to say what `cols` is. Each column asks about `cols` separately, -## and since roc-lang/roc#10984 those questions no longer share an answer. +## A row decoder written the way an application writes one. +## The compiler has to settle its type right here, before `query_many!` +## ever gets to say what `cols` is. Each call infers the type of `cols` separately, +## and since roc-lang/roc#10984 these types are no longer resolved together. ## ## The test is successful if this snippet compiles. expect {