roc-lang / roc

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

Roc panicked at 'no lambda set found' - Virtual DOM WIP Issue #5749

Open lukewilliamboswell opened 1 year ago

lukewilliamboswell commented 1 year ago

This is a minimal repro for the type check issue currently blocking virtual-dom-wip platform.

% roc test platform/Html/Internal/Test.roc 
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 'no lambda set found for (`16.IdentId(5)`, []): LambdaSet {
    set: [],
    args: [
        InLayout(
            48,
        ),
        InLayout(
            35,
        ),
    ],
    ret: InLayout(
        48,
    ),
    representation: InLayout(VOID),
    full_layout: InLayout(
        49,
    ),
}', crates/compiler/mono/src/layout.rs:1595:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
interface Test
    exposes []
    imports []

Html state : [Element Str U32 (List U32) (List (Html state))]
Handler state : [Normal (state, List (List U8) -> U32)]
DiffState state : { rendered : RenderedTree state, patches : List U32 }
RenderedTree state : {
    handlers : List (Result (Handler state) [DeletedHandler]),
}

createNode : DiffState state, Html state -> (DiffState state, U32)
createNode = \diffState, _ ->

    (updated, _) = List.walk [] (diffState, []) createChildNode

    (updated, 1)

createChildNode : (DiffState state, List U32), Html state -> (DiffState state, List U32)
createChildNode = \(diffState, ids), childHtml ->

    (updated, _) = createNode diffState childHtml

    (updated, List.append ids 3)

diff : DiffState state, Html state -> DiffState state
diff = \diffState, newNode ->
    replaceNode diffState 1 newNode

replaceNode : DiffState state, U32, Html state -> DiffState state
replaceNode = \diffState, _, newNode ->

    (updated, _) = createNode diffState newNode

    { updated & patches: List.append diffState.patches 1 }

expect
    State : { answer : U32 }

    diffStateBefore : DiffState State
    diffStateBefore = {
        rendered: { handlers: [] },
        patches: [],
    }

    newNode : Html State
    newNode = Element "" 0 [] []

    actual : DiffState State
    actual = diff diffStateBefore newNode

    actual.patches == []
ayazhafiz commented 1 year ago

even smaller reproducer

interface Test
    exposes [createNode]
    imports []

createNode = \diffState -> List.walk [] diffState createChildNode

createChildNode : U32, {} -> U32 
createChildNode = \diffState, {} -> createNode diffState

expect
    createNode 1 == 2
ayazhafiz commented 1 year ago

Solution is https://roc.zulipchat.com/#narrow/stream/395097-compiler-development/topic/checkmate/near/395423545, but needs implementation.