roc-lang / roc

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

Internal compiler expectation was broken #6243

Open Janiczek opened 10 months ago

Janiczek commented 10 months ago

Got this error message:

An internal compiler expectation was broken.
This is definitely a compiler bug.
Please file an issue here: https://github.com/roc-lang/roc/issues/new/choose
thread '<unnamed>' panicked at 'ambient functions don't unify', /Users/m1ci/actions-runner2/_work/roc/roc/crates/compiler/unify/src/unify.rs:201:18
stack backtrace:
   0:        0x104d7da18 - __mh_execute_header
   1:        0x10433586c - __mh_execute_header
   2:        0x104d796c0 - __mh_execute_header
   3:        0x104d7d830 - __mh_execute_header
   4:        0x104d8156c - __mh_execute_header
   5:        0x104d81318 - __mh_execute_header
   6:        0x104d81b50 - __mh_execute_header
   7:        0x104d8193c - __mh_execute_header
   8:        0x104d804d8 - __mh_execute_header
   9:        0x104d816f0 - __mh_execute_header
  10:        0x107793570 - __ZN4llvm15SmallVectorBaseIyE8grow_podEPvmm
  11:        0x10482d178 - __mh_execute_header
  12:        0x104853e18 - __mh_execute_header
  13:        0x1049d2a5c - __mh_execute_header
  14:        0x1049ce244 - __mh_execute_header
  15:        0x1049cc490 - __mh_execute_header
  16:        0x10490d8e8 - __mh_execute_header
  17:        0x1048a8370 - __mh_execute_header
  18:        0x1048a45e8 - __mh_execute_header
  19:        0x1048a7658 - __mh_execute_header
  20:        0x104d86944 - __mh_execute_header
  21:        0x188793034 - __pthread_joiner_wake

This happened during my solving of Advent of Code 2023-10. More specifically it happened as I tweaked the dbg statements in the findMaxDistance function:

 findMaxDistance : Grid,Nat,List XY -> Nat
 findMaxDistance = \grid,step,current ->
     dbg "----------"
-    dbg grid
+    dbg ("grid",grid)
-    dbg current
+    dbg ("curr",current)

     next = 
         current 
         |> List.joinMap (\xy -> findNeighbours grid xy)

-    dbg next
+    dbg ("next",next)

Version of Roc:

$ roc --version
roc nightly pre-release, built from commit 548f6532173 on Tue Dec  5 09:19:19 UTC 2023

The full source:

app "hello"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br" }
    imports [
        pf.Stdout,
        "../../input202310.txt" as realInput : Str
    ]
    provides [main] to pf

crashResult : Result a *, Str -> a
crashResult = \result,label ->
    when result is
        Ok a -> a
        Err _ -> crash label

testInput =
    """
    .....
    .S-7.
    .|.|.
    .L-J.
    .....
    """
    #"""
    #..F7.
    #.FJ|.
    #SJ.L7
    #|F--J
    #LJ...
    #"""

#main = part1 realInput
#main = part2 realInput
main = part1 testInput
#main = part2 testInput

part1 = \input ->
    grid = parse input

    #gridWithoutS = 
    #    gridWithS
    #    |> Dict.map (\xy,pipe ->
    #        if pipe == Start then
    #            sToPipe xy gridWithS
    #        else
    #            pipe
    #    )

    sPosition = 
        grid
        |> Dict.toList
        |> List.findFirst (\(_,pipe) -> pipe == Start)
        |> crashResult "S not found"
        |> (\(xy,_) -> xy)

    findMaxDistance grid 0 [sPosition]
    |> Inspect.toStr
    |> Stdout.line

findMaxDistance : Grid,Nat,List XY -> Nat
findMaxDistance = \grid,step,current ->
    dbg "----------"
    dbg ("grid",grid)
    dbg ("curr",current)

    next = 
        current 
        |> List.joinMap (\xy -> findNeighbours grid xy)

    dbg ("next",next)

    if List.isEmpty next then
        step
    else
        newGrid = current |> List.walk grid Dict.remove
        findMaxDistance newGrid (step + 1) next

findNeighbours : Grid,XY -> List XY
findNeighbours = \grid,xy ->
    tt = t xy
    bb = b xy
    ll = l xy
    rr = r xy
    [ if Dict.contains grid tt then Ok tt else Err NotFound
    , if Dict.contains grid bb then Ok bb else Err NotFound
    , if Dict.contains grid rr then Ok rr else Err NotFound
    , if Dict.contains grid ll then Ok ll else Err NotFound
    ]
    |> List.keepOks (\x -> x)

Pipe: [
    Vertical, # |
    Horizontal, # -
    TopLeft, # F
    TopRight, # 7
    BottomLeft, # L
    BottomRight, # J
    Start, # S
]
XY: (I64,I64)
Grid: Dict XY Pipe

t = \(x,y) -> (x,y-1)
b = \(x,y) -> (x,y+1)
l = \(x,y) -> (x-1,y)
r = \(x,y) -> (x+1,y)

sToPipe : XY,Grid -> Pipe
sToPipe = \xy,grid ->
    tt = grid |> Dict.get (t xy)
    bb = grid |> Dict.get (b xy)
    ll = grid |> Dict.get (l xy)
    rr = grid |> Dict.get (r xy)

    if (tt,bb) == (Ok Vertical, Ok Vertical) then
        Vertical
    else if (ll,rr) == (Ok Horizontal, Ok Horizontal) then
        Horizontal
    else if (tt,rr) == (Ok Vertical, Ok Horizontal) then
        BottomLeft
    else if (bb,rr) == (Ok Vertical, Ok Horizontal) then
        TopLeft
    else if (tt,ll) == (Ok Vertical, Ok Horizontal) then
        BottomRight
    else if (bb,ll) == (Ok Vertical, Ok Horizontal) then
        TopRight
    else
        crash "S not connected to two pipes!"

parse : Str -> Grid
parse = \input -> 
    input
    |> Str.split "\n"
    |> List.mapWithIndex (\row,y ->
        row
        |> Str.graphemes
        |> List.mapWithIndex (\char,x ->
            xy = (Num.intCast x, Num.intCast y)
            when char is
                "|" -> Ok (xy,Vertical)
                "-" -> Ok (xy,Horizontal)
                "J" -> Ok (xy,BottomRight)
                "L" -> Ok (xy,BottomLeft)
                "F" -> Ok (xy,TopLeft)
                "7" -> Ok (xy,TopRight)
                "S" -> Ok (xy,Start)
                "." -> Err DoNotCareAboutGround
                _ -> crash "parse: unknown char"
        )
        |> List.keepOks (\x -> x)
    )
    |> List.join
    |> Dict.fromList
Janiczek commented 10 months ago

The issue seems to go away when I remove the tuple from the grid:

-    dbg ("grid",grid)
+    dbg grid
JRI98 commented 8 months ago

Simpler reproduction:

app "hello"
    packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.7.0/bkGby8jb0tmZYsy2hg1E_B2QrCgcSTxdUlHtETwm5m4.tar.br" }
    imports []
    provides [main] to pf

main =
    dbg ("grid", grid)

    crash ""

Grid : Dict I64 I64

grid : Grid
grid =
    Dict.empty {}