Fix sqlite decoder inference - #475
Merged
lukewilliamboswell merged 2 commits intoAug 31, 2026
Merged
Conversation
added 2 commits
August 31, 2026 09:41
`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.
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).
lukewilliamboswell
approved these changes
Aug 31, 2026
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.
The SQLite examples stop type-checking on any nightly from
nightly-2026-08-30-34e7489onward.Same error at
examples/sqlite-everything.roc:204and:219.Root cause
lookup_value!found a column withcols.find_first_index(...). The decoder combinators are deliberately unannotated, so the compiler has not worked out whatcolsis at that point, and it carries the question into whatever decoder an application writes, where it still cannot be answered. roc-lang/roc#10984 stopped those questions sharing an answer between calls, so a decoder with a name of its own asks aboutcolsonce per column and gets nowhere.Only named decoders break. The inline
rows: |cols| |stmt| ...form waits forquery_many!to say whatcolsis, which is why the count is three and not more.Applications cannot work around it.
query_many!unwraps the opaqueStmtand hands the decoder aHost.SqliteStmt, andHostis not in the platform'sexposeslist, so there is no annotation an app is able to write.Fix
lookup_value!:List.find_first_index(cols, ...). That says which type the lookup comes from, socolssettles as aList(Str)where it is asked about and nothing is left for the application to answer.platform/Path.roc:558already reads the same lookup this wayexpectcovering a row decoder with a name of its own, which is the shape that breaksnightly-2026-08-23-fb208batonightly-2026-08-30-34e7489. #10984 does not exist at the old pin, so neither the bug nor the test guarding it shows up there. I will drop bumping the nightly if you would rather move the pin separately.No signature changes, so
src/roc_platform_abi.rsandci/regenerate_glue.share untouched:lookup_value!is module-private, sits outside theSqlite :: [].{}block, and appears in norequires,providesorhostedblock.Verification
The test was checked against the bug on
nightly-2026-08-30-34e7489:platform/Sqlite.rocroc test platform/main.rocNote that
roc testprintsAll (208) tests passedeven when the type error fires, so the exit code is the signal here, not the summary line../scripts/test.pywas not run. The build and run stages, and the twotest_spec.jsoncases per SQLite example, are for CI to confirm. The change is Roc-only and moves no program output.roc fmt --checkalready fails onplatform/Cmd.roc,platform/InternalSqlite.rocandplatform/Url.rocon both nightlies, unrelated to this change and untouched by it.