roc-lang / roc

A fast, friendly, functional language.
https://roc-lang.org
Universal Permissive License v1.0
4.09k stars 288 forks source link

dbg index out of bounds #5984

Open Anton-4 opened 10 months ago

Anton-4 commented 10 months ago
❯ ./target/release/roc examples/helloWorld.roc 
thread 'main' panicked at 'index out of bounds: the len is 8 but the index is 169', /home/username/gitrepos/roc4/roc/crates/repl_eval/src/eval.rs:898:48
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I did not minimize the code completely because these types of issues should be fixed once we use inspect for dbg. Similar issue with minimized example here.

# this source is partially minimized, see original at https://github.com/salarii/peek/blob/e6e0b29fd5b715cb05d0bdfef2a16194f474d01d/regex.roc

app "reg"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.5.0/Cufzl36_SnJ4QbOoEmiJ5dIpUxBvdB3NEySvuH82Wio.tar.br" }
    imports [pf.Stdout]
    provides [main] to pf

firstStagePatterns = [
        { tag : Dot, str : "."},
    ]

priorities =
    Dict.empty {}
    |> Dict.insert Empty -1
    |> Dict.insert Character 0
    |> Dict.insert Dot 1

emptyNode = { locked : Bool.false, children :  [], value : [] }

treeBase = 
    {cnt : 0, content : Dict.empty {} }
    |> addElement  0 emptyNode

createParsingRecord = \ regex, meta ->
     { regex : regex, current : regex, matched : [], result : Bool.false, missed : [], left : [] , captured : treeBase, meta : meta, strict : No } 

checkMatchingValidity = \ matchingResult ->
    when matchingResult.strict is 
        No -> Bool.true 
        Front -> List.isEmpty  matchingResult.missed
        Back -> List.isEmpty  matchingResult.left 
        Both -> (List.isEmpty  matchingResult.missed) && (List.isEmpty  matchingResult.left)

modifyLastInList = \ lst, elem ->
    List.dropLast lst 1
    |> List.append elem

getPrioToken = \ patterns ->
    if List.isEmpty patterns then
        Err NoTokens
    else
        List.walk patterns (Err Empty) (\ state, pattern -> 
            when state is 
                Err Empty ->
                    when Dict.get priorities  pattern.tag is
                        Ok _ -> Ok pattern
                        Err _ -> Err PriorityListErr 
                Ok prevPat ->  

                    when Dict.get priorities prevPat.tag is
                        Ok val1 ->
                            when Dict.get priorities  pattern.tag is
                                Ok val2 ->
                                    if val2 > val1 then 
                                        Ok pattern
                                    else 
                                        state
                                Err _ -> Err PriorityListErr 
                        Err _ -> Err PriorityListErr
                Err message -> Err message 
        )

createToken = \ token, serie, capture ->
    { token :token, serie : serie, capture : capture  }

regexSeedPattern = [
    { tag : Character, tokens : [ createToken  Dot  Once Bool.false ] } ]

#  test  this, I could not figure  out  how to do this properly 
splitChainOnSeparators = \ chain, inputLst ->
    when List.first chain is 
        Ok elem ->
            when elem.token is 
                Separator -> 

                        List.walk ( splitChainOnSeparators (List.dropFirst chain 1) []) [] ( \ state, lst ->
                            List.append state lst
                        )
                        |>   List.append []
                Sequence  inChain ->

                    partialSeqResult =
                        List.walk ( splitChainOnSeparators inChain []) [] ( \ outState, frontLst ->                               

                            List.walk ( splitChainOnSeparators (List.dropFirst chain 1) []) outState ( \ state, lst ->                                
                                List.append state  ( List.concat [ {elem & token : Sequence frontLst } ]  lst) 
                            )        
                        )   

                    when List.last partialSeqResult is
                        Ok activElem ->
                            List.dropLast partialSeqResult 1
                            |> List.walk  [] ( \ state,  lst ->
                                List.append state (List.concat inputLst lst))
                            |> List.append  activElem
                        Err _ ->
                            []

                _ ->

                    partialResult =
                        List.walk ( splitChainOnSeparators (List.dropFirst chain 1) (List.append inputLst elem )) [] ( \ state, lst ->
                                List.append state lst
                        )

                    when List.last partialResult is 
                        Ok lst -> 
                            modifyLastInList partialResult  (List.concat [elem] lst)  
                        Err _ -> 
                            []

        Err _ ->
            [[]]

evalRegex = \ utfLst, patterns, regex ->
    if List.isEmpty utfLst then
        Ok regex
    else
        List.walk patterns [] ( \ state, pattern ->
            out = checkMatching utfLst pattern.tokens
            if out.result == Bool.true   && List.isEmpty out.missed then
                List.append state { tag : pattern.tag, parsedResult : out } 
            else
                state 
            )
        |> getPrioToken
        |> ( \ prioToken ->
            when prioToken is
                Ok token -> evalRegex token.parsedResult.left patterns  ( List.append regex token ) 
                Err message ->  Err message  )

checkMatching = \ utfLst, reg  ->

    matchStr = \ utf, pattern ->
        when pattern is 
            Character val ->
                if val == utf then
                    Consume    
                else
                    NoMatch
            Dot ->
                Consume
            _ -> NoMatch

    matchUtf = ( \ utf, tokenMeta ->
        result = matchStr utf tokenMeta.token

        when result is
            Consume -> Consume tokenMeta 
            NoMatch -> NoMatch tokenMeta 
    )

    updateRegex = (\regex ->   
        List.walk  regex [] ( \ state, regItem ->
            when List.first regItem.current is 
                Ok pat ->
                    when pat.token  is
                        Sequence  chain ->
                            when pat.serie is 
                                AtLeastOne ->           
                                    changeFront = 
                                        (List.dropFirst regItem.current 1)
                                        |> List.prepend { pat & serie : ZeroOrMore }

                                    List.concat chain changeFront
                                    |> (\ updatedCurrent ->  List.append state {regItem & current : updatedCurrent} )  
                                ZeroOrMore ->

                                    List.append state {regItem & current : (List.dropFirst regItem.current 1)}  
                                    |> List.append 
                                        (List.concat chain (List.dropFirst regItem.current 1)
                                        |> (\ updatedCurrent ->  {regItem & current : updatedCurrent, meta : Active} ))
                                NTimes cnt -> 
                                    concatIter = (\ n , lst, stored ->
                                        if n == 0 then 
                                            stored
                                        else 
                                            concatIter (n-1) lst (List.concat lst stored  ))

                                    List.concat (concatIter cnt chain  [] ) (List.dropFirst regItem.current 1)
                                    |> (\ updatedCurrent ->  List.append state {regItem & current : updatedCurrent} )  
                                Once ->
                                    List.concat chain (List.dropFirst regItem.current 1)
                                    |> (\ updatedCurrent ->  List.append state {regItem & current : updatedCurrent} )  
                        _ -> List.append state regItem

                Err _ -> List.append state regItem )
        )

    getFirstPat = (\  state  ->  
        if state.meta == Inactive then
            Inactive state
        else
            when List.first state.current is
                Ok pat -> 
                    Active { pattern : pat , state : state } 
                Err _ ->
                    if state.meta == Origin then
                        # BUG  in this  line
                        #getFirstPat  { state & current : state.regex } 
                        getFirstPat  { regex : state.regex, current : state.regex, matched : state.matched, result : state.result, missed : state.missed, left : state.left, captured : state.captured, meta : state.meta, strict : state.strict } 

                    else   
                        Inactive {state & meta : Inactive } 
            )

    complexSearch = 
        List.walk utfLst [createParsingRecord reg Origin]  ( \ outState, utf ->

            updatedStates = updateRegex outState 

            List.walk updatedStates [] ( \ state, processedReg ->   

                if processedReg.result == Bool.true then
                    List.append state { processedReg & left : List.append  processedReg.left utf} 
                else   
                    manageIteration = ( \ inProcessedReg,curState ->

                        when getFirstPat inProcessedReg is
                            Inactive _patternSet ->
                                List.append curState inProcessedReg
                            Active matchThis ->
                                toUpdateState = matchThis.state  
                                if matchThis.pattern.token == CaptureOpen then
                                    tmpState = {toUpdateState & current : List.dropFirst toUpdateState.current 1}

                                    manageIteration { tmpState &  captured : (composeMatchedStructure tmpState.captured  0 CaptureOpen) }  curState

                                else if matchThis.pattern.token == CaptureClose then

                                    tmpState = {toUpdateState & current : List.dropFirst toUpdateState.current 1}    
                                    manageIteration { tmpState &   captured : composeMatchedStructure tmpState.captured  0 CaptureClose } curState
                                else

                                    updatedState = matchThis.state
                                    current = List.dropFirst  updatedState.current  1
                                    #   BUG  this  crashes 
                                    # ppp = List.isEmpty current == Bool.true 

                                    updatedCapture =
                                        if matchThis.pattern.capture == Bool.true then
                                            when  changeValue updatedState.captured 0 utf  is 
                                                Ok updatedTree -> updatedTree
                                                Err _ ->  updatedState.captured
                                        else
                                            updatedState.captured

                                    when matchUtf utf  matchThis.pattern is 
                                        Consume _updatedToken ->
                                            if List.len current == 0 then
                                                List.append curState { updatedState &  matched : List.append updatedState.matched  utf, current : current, result : Bool.true, left : [], captured : updatedCapture}
                                            else
                                                List.append curState { updatedState & matched : List.append updatedState.matched  utf, current : current, left : [], captured : updatedCapture} 
                                        NoMatch _ ->

                                                # BUG second line 
                                                # updateMissed = List.concat updatedState.missed  updatedState.matched

                                                #List.append curState { updatedState &  matched : [], current : updatedState.regex, missed : List.append updateMissed utf, left : [], captured : treeBase}
                                                List.append curState { regex : updatedState.regex, current : updatedState.regex, matched : [], result : updatedState.result, missed : updatedState.missed, left : updatedState.left, captured : treeBase, meta : updatedState.meta, strict : updatedState.strict }

                                        _ -> curState  
                                )
                    manageIteration processedReg state ) 
        )
    List.walk complexSearch  (createParsingRecord reg Inactive) ( \ state, parsResult -> 
        if state.result == Bool.true then
            if (List.len parsResult.matched > List.len state.matched ) && (checkMatchingValidity state) then 
                parsResult
            else 
                state
        else 
            parsResult )

getRegexTokens = \ result  -> 
    when result.tag is 
        Character-> 
            when List.first result.parsedResult.matched is 
                Ok  matched  -> Ok [(createToken  ( Character matched )  Once Bool.false )]
                Err  _  -> Err "character  tag problem"

        _ -> Err "wrong tag"

regexCreationStage = \ inPatterns, ignitionPatterns ->

    regPatterns = 
        List.walk inPatterns (Ok []) ( \ state, pat->
            when state is 
                Ok patterns -> 
                    when evalRegex (Str.toUtf8  pat.str ) ignitionPatterns [] is 
                        Ok results ->
                            List.walk  results (Ok []) ( \ inState, result ->
                                when inState is 
                                    Ok patLst ->
                                        when  getRegexTokens result is 
                                            Ok tokens -> 
                                                workaround = 
                                                    List.walk  tokens [] ( \ workState, token -> 
                                                        List.append workState (createToken token.token token.serie  token.capture) )
                                                # !!!!!!!!!!! crashes  here Ok [{ tag : pat.tag, tokens : tokens }]
                                                Ok (List.concat patLst  workaround  )    

                                            Err message -> Err message 
                                    Err  message -> Err message     

                            )
                            |> (\ inTokensResult ->
                                when  inTokensResult is 
                                    Ok inTokens ->  
                                        Ok ( List.append patterns { tag : pat.tag, tokens : inTokens } )
                                    Err message ->  Err message )

                        Err Empty ->  Err "Empty" 
                        Err NoTokens ->  Err "NoTokens"
                        Err PriorityListErr ->  Err "PriorityListErr"
                Err message ->  Err message )
    when regPatterns is 
        Ok patterns ->
            Ok ( List.concat  ignitionPatterns  patterns )
        Err  message  -> Err  message  

stagesCreationRegex  = \ _param -> 
    regexCreationStage firstStagePatterns regexSeedPattern
    #stage1  = regexCreationStage firstStagePatterns regexSeedPattern
    #when stage1 is 
    #    Ok stage1Pat -> 
    #        regexCreationStage secondStagePatterns stage1Pat

    #    Err message -> 
    #        Err message

regexCreationStage2  = \ str, patterns, currReg ->
    ( evalRegex (Str.toUtf8  str) patterns currReg )
    |> ( \ resultSet -> 
        when resultSet is
            Ok  results ->
                List.walk results (Ok { lst : [] , capture : Bool.false }) ( \ outState, result  ->
                    when outState is 
                        Err message -> Err message 
                        Ok state ->
                            modifLastInChain = (\ chainLst, token ->
                                when List.last chainLst is 
                                    Ok elem ->
                                        when elem.token is 
                                            Sequence  chain ->
                                                when List.last chain is
                                                    Ok _lastOnChain ->
                                                        when token.token is 
                                                            CaptureClose -> 
                                                                List.append chainLst token            
                                                            _ -> 
                                                                modifyLastInList chainLst (createToken (Sequence ( modifLastInChain chain token))  Once Bool.false)

                                                    Err _ ->
                                                        modifyLastInList  chainLst  (createToken (Sequence ( modifLastInChain chain token))  Once Bool.false)
                                            _ ->  
                                                List.append chainLst token                  
                                    Err _ ->
                                        List.append chainLst token

                            )

                            when  result.tag is 
                                Character ->
                                    when List.first result.parsedResult.matched is 
                                        Ok  matched  ->
                                            Ok { state &  lst : modifLastInChain state.lst  (createToken (Character matched) Once state.capture) }
                                        Err _ -> Err "parser  match problem"

                                Dot ->
                                    Ok { state &  lst : modifLastInChain state.lst (createToken Dot Once state.capture )  }
                                CaptureOpen ->

                                    openLst = 
                                        modifLastInChain state.lst (createToken CaptureOpen Once Bool.false)
                                        |> modifLastInChain  (createToken (Sequence []) Once Bool.false)
                                    Ok { lst : openLst, capture : Bool.true}
                                Digit ->
                                    Ok { state &  lst : modifLastInChain state.lst (createToken Digit Once Bool.false )  }
                                NoDigit ->
                                    Ok { state &  lst : modifLastInChain state.lst (createToken NoDigit Once Bool.false )  }
                                Alphanumeric ->
                                    limitRangToken = LimitRanges [{ left : 'A', right : 'Z' },{ left : 'a', right : 'z' },{ left : '0', right : '9' }]
                                    Ok { state &  lst : modifLastInChain state.lst (createToken limitRangToken Once Bool.false )  }

                                Empty -> Err "Empty"  
                        )
                |> (\ tokenLst -> 
                    when tokenLst is 
                        Ok lstRec ->
                            Ok lstRec.lst
                        Err message -> Err message  )

            Err Empty ->  Err "Empty" 
            Err NoTokens ->  Err "NoTokens"
            Err PriorityListErr ->  Err "PriorityListErr"
    )

#    checkMatching str reg  ->
# create  patterns  and  than  parse  string with it     

availableRegex = stagesCreationRegex [] 

# maybe at some point add some additional error handling ??

# to be replaced 

addElement = \ tree, parentId ,node -> 
    when Dict.get tree.content parentId  is 
        Ok element -> 
            updatedContent = 
                Dict.remove tree.content parentId
                |> Dict.insert parentId {element  & children : (List.append element.children tree.cnt )}

            { cnt : tree.cnt + 1, content : (Dict.insert updatedContent  tree.cnt node )  }          
        Err _ -> { cnt : tree.cnt + 1, content : Dict.insert tree.content  tree.cnt node }

changeElement = \ tree, id ,node -> 
    when Dict.get tree.content id  is 
        Ok _element -> 
            updatedContent = 
                Dict.remove tree.content id
                |> Dict.insert id node

            { tree & content : updatedContent }          
        Err _ -> { cnt : tree.cnt + 1, content : Dict.insert tree.content  tree.cnt node }

modifyActive = \ tree, headId, op ->
    when Dict.get tree.content headId  is 
        Ok head -> 
            if List.isEmpty head.children == Bool.true then
                op headId tree
            else 
                when List.last head.children is 
                    Ok nodeId ->
                        when Dict.get tree.content nodeId is 
                            Ok child ->
                                if child.locked == Bool.true then
                                    op headId tree
                                else 
                                    modifyActive tree nodeId op
                            Err _ -> Err  "internal logic error"
                    Err _ -> Err  "internal logic error"

        Err _ -> Err  "wrong tree node id"

changeValue = \ tree, id, value-> 
    modify = 
        \ idValue, treeValue ->
            when Dict.get treeValue.content idValue is 
                Ok node ->
                    Ok (changeElement treeValue idValue {node & value : List.append node.value value  } )
                Err _ -> Err  "internal logic error"

    modifyActive tree id modify

composeMatchedStructure = \ tree, id,tag ->

    addNewNode = \ idNew, treeNew -> Ok (addElement treeNew idNew emptyNode)

    lockNode = 
        \ idLock, treeLocked ->
            when Dict.get treeLocked.content idLock is 
                Ok node ->
                    Ok (changeElement treeLocked idLock {node & locked : Bool.true } )
                Err _ -> Err  "internal logic error"
    result = 
        when tag is 
            CaptureOpen -> 
                if Dict.isEmpty tree.content == Bool.false then 
                    modifyActive tree id addNewNode 
                else
                    Err  "internal logic error"
            CaptureClose ->
                modifyActive tree id lockNode
    when result is
        Ok newTree -> newTree
        Err _  -> tree

parseStr = \ str, pattern -> 
    when availableRegex is 
        Ok stage1Pat -> 
            tokensFromUserInputResult = regexCreationStage2 pattern stage1Pat  []

            when tokensFromUserInputResult is 
                Ok tokensFromUserInput ->
                    independentChainlst = splitChainOnSeparators tokensFromUserInput []
                    # for now get longest maybe??

                    Ok (List.walk independentChainlst (createParsingRecord [] Inactive)  ( \ state, regexParser ->  
                        parsResult = checkMatching (Str.toUtf8  str ) regexParser    
                        if state.result then
                            if List.len parsResult.matched > List.len state.matched  then 
                                parsResult
                            else 
                                state
                            else 
                                parsResult ))
                Err message -> 
                    Err (Str.concat "You screwed up something, or not supported construction, or internal bug \n"  message )

        Err message -> 
            Err  (Str.concat "This is internal regex error not your fault\n"  message )

main =
    pp =  parseStr  "sss"   "a"
    # BUG  as usuall problem with dbg     
    dbg  pp 

    Stdout.line "outStr"
AjaiKN commented 2 months ago

I'm guessing this is probably the same issue? Tested on commit 5d09479fd365d8fbaefa640830725eb91955f1a7

# Thing.roc
module [InputType]

InputType t1 t2 : [
    A t2 (InputType t1 t2),
    B t1,
    C,
    D,
    E,
    F,
    G,
    H,
    I,
] where t1 implements Eq

OutputType t1 t2 : List [Out t2] where t1 implements Eq

f : OutputType t1 t2, InputType t1 t2 -> OutputType t1 t2
f = \out, inp ->
    when inp is
        A someT2 _ ->
            out |> List.append (Out someT2)

        B _ | C | D | E | F | G | H | I ->
            out

expect
    left = A Y (B Z)
    f [] left == []
❯ cargo run -- test Thing.roc
    Finished dev [unoptimized + debuginfo] target(s) in 0.59s
     Running `/Users/ajainelson/prog/roc/roc/target/debug/roc test Thing.roc`
thread 'main' panicked at /Users/ajainelson/prog/roc/roc/crates/repl_eval/src/eval.rs:918:64:
index out of bounds: the len is 8 but the index is 169
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Backtrace ``` ❯ RUST_BACKTRACE=full cargo run -- test Thing.roc Finished dev [unoptimized + debuginfo] target(s) in 0.37s Running `/Users/ajainelson/prog/roc/roc/target/debug/roc test Thing.roc` thread 'main' panicked at /Users/ajainelson/prog/roc/roc/crates/repl_eval/src/eval.rs:918:64: index out of bounds: the len is 8 but the index is 169 stack backtrace: 0: 0x107dee5d0 - std::backtrace_rs::backtrace::libunwind::trace::hadefa2fe489b32be at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/../../backtrace/src/backtrace/libunwind.rs:104:5 1: 0x107dee5d0 - std::backtrace_rs::backtrace::trace_unsynchronized::h37e8bb3c3fd9c67c at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5 2: 0x107dee5d0 - std::sys_common::backtrace::_print_fmt::h4994a90b70e9aaa7 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/sys_common/backtrace.rs:68:5 3: 0x107dee5d0 - ::fmt::hb478ebbfb46e27ce at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/sys_common/backtrace.rs:44:22 4: 0x107e122c4 - core::fmt::rt::Argument::fmt::hfe2e626e52db21d5 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/fmt/rt.rs:142:9 5: 0x107e122c4 - core::fmt::write::he4d5fa2daff1f531 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/fmt/mod.rs:1120:17 6: 0x107dea618 - std::io::Write::write_fmt::hc5a47a68eba63d9f at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/io/mod.rs:1810:15 7: 0x107dee404 - std::sys_common::backtrace::_print::hd47355bf70e1c2da at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/sys_common/backtrace.rs:47:5 8: 0x107dee404 - std::sys_common::backtrace::print::h79bd952cc5812e7a at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/sys_common/backtrace.rs:34:9 9: 0x107defa28 - std::panicking::default_hook::{{closure}}::h82301f6222887737 10: 0x107def770 - std::panicking::default_hook::h1e49abbb3f1d7dbf at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:292:9 11: 0x107defe70 - std::panicking::rust_panic_with_hook::h1e70c5d905e30e9d at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:779:13 12: 0x107defd64 - std::panicking::begin_panic_handler::{{closure}}::h399e32952efd26a4 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:657:13 13: 0x107deea54 - std::sys_common::backtrace::__rust_end_short_backtrace::h2ab87f841a2323e7 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/sys_common/backtrace.rs:171:18 14: 0x107defaec - rust_begin_unwind at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:645:5 15: 0x107e801f4 - core::panicking::panic_fmt::h33e40d2a93cab78f at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:72:14 16: 0x107e80394 - core::panicking::panic_bounds_check::h68378bb80e53ac8a at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/panicking.rs:208:5 17: 0x10714c79c - index<(roc_mono::layout::TagOrClosure, &[roc_mono::layout::intern::InLayout])> at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/slice/index.rs:255:10 18: 0x1072fdb84 - index<(roc_mono::layout::TagOrClosure, &[roc_mono::layout::intern::InLayout]), usize> at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/slice/index.rs:18:9 19: 0x1072fbdc8 - index<(roc_mono::layout::TagOrClosure, &[roc_mono::layout::intern::InLayout]), usize> at /Users/ajainelson/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bumpalo-3.14.0/src/collections/vec.rs:1928:9 20: 0x1048902c8 - addr_to_ast at /Users/ajainelson/prog/roc/roc/crates/repl_eval/src/eval.rs:918:64 21: 0x104894edc - {closure#6} at /Users/ajainelson/prog/roc/roc/crates/repl_eval/src/eval.rs:538:21 22: 0x10487fcdc - call_function_dynamic_size> at /Users/ajainelson/prog/roc/roc/crates/repl_expect/src/app.rs:146:14 23: 0x104894cf4 - jit_to_ast_help at /Users/ajainelson/prog/roc/roc/crates/repl_eval/src/eval.rs:534:29 24: 0x10488ce30 - jit_to_ast at /Users/ajainelson/prog/roc/roc/crates/repl_eval/src/eval.rs:70:13 25: 0x1048a4514 - get_values at /Users/ajainelson/prog/roc/roc/crates/repl_expect/src/lib.rs:70:20 26: 0x104854b84 - render_expect_failure at /Users/ajainelson/prog/roc/roc/crates/repl_expect/src/run.rs:488:44 27: 0x104854584 - run_expect_pure at /Users/ajainelson/prog/roc/roc/crates/repl_expect/src/run.rs:275:26 28: 0x104854fc8 - run_expects_with_memory at /Users/ajainelson/prog/roc/roc/crates/repl_expect/src/run.rs:218:22 29: 0x1048548d0 - run_toplevel_expects at /Users/ajainelson/prog/roc/roc/crates/repl_expect/src/run.rs:168:5 30: 0x10486d920 - test at /Users/ajainelson/prog/roc/roc/crates/cli/src/lib.rs:583:44 31: 0x1046dd854 - main at /Users/ajainelson/prog/roc/roc/crates/cli/src/main.rs:80:17 32: 0x1046df1a4 - call_once core::result::Result<(), std::io::error::Error>, ()> at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/ops/function.rs:250:5 33: 0x1046debf8 - __rust_begin_short_backtrace core::result::Result<(), std::io::error::Error>, core::result::Result<(), std::io::error::Error>> at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/sys_common/backtrace.rs:155:18 34: 0x1046def38 - {closure#0}> at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/rt.rs:166:18 35: 0x107de266c - core::ops::function::impls:: for &F>::call_once::hde2a2ae1d756c37f at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/core/src/ops/function.rs:284:13 36: 0x107de266c - std::panicking::try::do_call::h96b73f4da16ee7c5 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:552:40 37: 0x107de266c - std::panicking::try::h2cb0c14c1266f147 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:516:19 38: 0x107de266c - std::panic::catch_unwind::hb8cd2580f659030d at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panic.rs:142:14 39: 0x107de266c - std::rt::lang_start_internal::{{closure}}::h00f9c2d0117ea0ef at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/rt.rs:148:48 40: 0x107de266c - std::panicking::try::do_call::h134dfd8876bcc105 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:552:40 41: 0x107de266c - std::panicking::try::h6595e056250d6043 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panicking.rs:516:19 42: 0x107de266c - std::panic::catch_unwind::haad85d5172c9b53a at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/panic.rs:142:14 43: 0x107de266c - std::rt::lang_start_internal::hf4f3eb1e51305b96 at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/rt.rs:148:20 44: 0x1046def10 - lang_start> at /rustc/07dca489ac2d933c78d3c5158e3f43beefeb02ce/library/std/src/rt.rs:165:17 45: 0x1046ddfcc - _main ```