Stream: bugs

Topic: (Probable) memory corruption issue with List.len()


view this post on Zulip Ian McLerran (May 05 2026 at 01:46):

I have two different minimum reproductions that seem to demonstrate the failure in two slightly different ways:

Notice that in the first example, dbg list.len() correctly prints 1, but that dbg $idx prints {}. However, in the second example with the while loop, dbg list.len() prints a floating point number, and dbg $idx prints a different floating point number, from which the loop begins iterating.

Min :: [].{
    find_last_indxex : List(a) -> Try(U64, [NotFound])
    find_last_index = |list| {
        dbg list.len()
        var $idx = list.len()
        dbg $idx
        return Err(NotFound)
    }
}
expect [0]->find_last_index() == Err(NotFound)
$ roc test Min.roc --no-cache
[dbg] 1
[dbg] {}
All (1) tests passed in 31.5 ms.
Min :: [].{
    find_last_indxex : List(a) -> Try(U64, [NotFound])
    find_last_index = |list| {
        dbg list.len()
        var $idx = list.len()
        dbg $idx
        while $idx > 0 {
            $idx = $idx - 1
            dbg $idx
        }
        return Err(NotFound)
    }
}
expect [0]->find_last_index() == Err(NotFound)
$ roc test Min.roc --no-cache
[dbg] -113427455640312821166.756031859729104895
[dbg] 756.316507022091616257
[dbg] 755.316507022091616257
[dbg] 754.316507022091616257
...
[dbg] 0.316507022091616257
[dbg] -0.683492977908383743
All (1) tests passed in 39.4 ms.

view this post on Zulip Ian McLerran (May 05 2026 at 02:01):

Under some scenarios, I have also produced segfaults, such as here:

find_last_indxex : List(a), (a -> Bool) -> Try(U64, [NotFound])
find_last_index = |list, _predicate| {
    var $idx = list.len()

    for _item in list.reverse() {
        dbg $idx
        $idx = $idx - 1
    }
    return Err(NotFound)
}
Segmentation fault (SIGSEGV) in the Roc compiler.
Fault address: 0x444

Please report this issue at: https://github.com/roc-lang/roc/issues

EDIT: This is an unrelated bug. It can be reproduced with:

Min2 :: [].{
    find_last_indxex : List(a) -> Try(U64, [NotFound])
    find_last_index = |list| {
        for _item in list.reverse() {}
        return Err(NotFound)
    }
}
expect [0]->find_last_index() == Err(NotFound)

view this post on Zulip Anton (May 05 2026 at 09:14):

Can you make two issues for this @Ian McLerran? I'm sick so I won't be able to look at it immediately.

view this post on Zulip Ian McLerran (May 05 2026 at 19:03):

Sorry to hear you're feeling sick @Anton! Yeah, I'll file the related issues. Hope ya feel better soon!

view this post on Zulip Ian McLerran (May 06 2026 at 19:22):

Issues filed at #9390 and #9389


Last updated: May 23 2026 at 12:51 UTC