Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler crash with number literal in guard #7302

Open
gamebox opened this issue Dec 3, 2024 · 7 comments
Open

Compiler crash with number literal in guard #7302

gamebox opened this issue Dec 3, 2024 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@gamebox
Copy link
Collaborator

gamebox commented Dec 3, 2024

Full code is here: https://github.com/gamebox/aoc-2024/blob/main/day3/puzzle2/main.roc

@Anton-4 said it was fine to not have a minimal reproduction

I get the following error when running, testing, or building:

thread '<unnamed>' panicked at crates/compiler/mono/src/ir/decision_tree.rs:777:17:
IntLiteral([44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], U8)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
@gamebox
Copy link
Collaborator Author

gamebox commented Dec 3, 2024

I checked into this with a little more debugging output and it has something to do with the first two match clauses here:

when (state, char, opState) is
       # ...many more clauses above
        (ExpectingX, d, s) if (d >= '0' && d <= '9') ->
            (muls, BuildingX (Num.toI64 (d - '0')), s)

        (BuildingX num, d, s) if (d >= '0' && d <= '9') && (num < 100) ->
            (muls, BuildingX ((num * 10) + (Num.toI64 (d - '0'))), s)

        (BuildingX num, 44, s) if (num < 1000) ->
            (muls, ExpectingY num, s)

      # more clauses below....

That third match clause is where the issue happens. It looks like it's trying to consider it part of the guard in the clause above. Here's what the start and end for this branch looks like printing using formatted debug (:#?):

Start

[
    (
        [
            TagIndex {
                index: 0,
                tag_id: 0,
            },
        ],
        AppliedTag {
            tag_name: 'BuildingX',
            tag_id: 6,
            arguments: [
                (
                    Identifier(
                        `#UserApp.num`,
                    ),
                    InLayout(I64),
                ),
            ],
            layout: NonRecursive(
                [
                    [],
                    [],
                    [],
                    [],
                    [],
                    [],
                    [
                        InLayout(I64),
                    ],
                    [
                        InLayout(I64),
                        InLayout(I64),
                    ],
                    [],
                    [],
                    [],
                    [],
                    [],
                    [
                        InLayout(I64),
                    ],
                    [],
                ],
            ),
            union: Union {
                alternatives: [
                    Ctor {
                        name: Tag(
                            'BuildingDoOrDontStartD',
                        ),
                        tag_id: TagId(
                            0,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'BuildingDoOrDontStartDO',
                        ),
                        tag_id: TagId(
                            1,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'BuildingDontStartDON',
                        ),
                        tag_id: TagId(
                            2,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'BuildingDontStartDONQ',
                        ),
                        tag_id: TagId(
                            3,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'BuildingMulStartM',
                        ),
                        tag_id: TagId(
                            4,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'BuildingMulStartMU',
                        ),
                        tag_id: TagId(
                            5,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'BuildingX',
                        ),
                        tag_id: TagId(
                            6,
                        ),
                        arity: 1,
                    },
                    Ctor {
                        name: Tag(
                            'BuildingY',
                        ),
                        tag_id: TagId(
                            7,
                        ),
                        arity: 2,
                    },
                    Ctor {
                        name: Tag(
                            'ExpectingDoClose',
                        ),
                        tag_id: TagId(
                            8,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'ExpectingDontClose',
                        ),
                        tag_id: TagId(
                            9,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'ExpectingDontOpen',
                        ),
                        tag_id: TagId(
                            10,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'ExpectingMulOpen',
                        ),
                        tag_id: TagId(
                            11,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'ExpectingX',
                        ),
                        tag_id: TagId(
                            12,
                        ),
                        arity: 0,
                    },
                    Ctor {
                        name: Tag(
                            'ExpectingY',
                        ),
                        tag_id: TagId(
                            13,
                        ),
                        arity: 1,
                    },
                    Ctor {
                        name: Tag(
                            'LookingForOpStart',
                        ),
                        tag_id: TagId(
                            14,
                        ),
                        arity: 0,
                    },
                ],
                render_as: Tag,
            },
        },
    ),
]

The pattern:

IntLiteral([44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], U8)

The end

[
    (
        [
            TagIndex {
                index: 2,
                tag_id: 0,
            },
        ],
        Identifier(
            `#UserApp.s`,
        ),
    ),
]

@gamebox
Copy link
Collaborator Author

gamebox commented Dec 3, 2024

The44 number literal in the pattern looks like the desugared version of the ',' char literal in that match clause

@gamebox
Copy link
Collaborator Author

gamebox commented Dec 3, 2024

I've done a lot of small syntactic tweaks and this is the only two things that fix it, remove the first guard or the second guard:

        (ExpectingX, d, s) ->
            num = numFromDigit d
            ps = BuildingX num
            (muls, ps, s)

        (BuildingX num, d, s) if (isLessThreeDigits d num) ->
            x = addDigit num d
            ps = BuildingX x
            (muls, ps, s)

        # 44 is ,
        (BuildingX num, 44, s) if (isNoMoreThanThreeDigits num) ->
            ps = ExpectingY num
            (muls, ps, s)
        (ExpectingX, d, s) if (isDigit d) ->
            num = numFromDigit d
            ps = BuildingX num
            (muls, ps, s)

        (BuildingX num, d, s) ->
            x = addDigit num d
            ps = BuildingX x
            (muls, ps, s)

        # 44 is ,
        (BuildingX num, 44, s) if (isNoMoreThanThreeDigits num) ->
            ps = ExpectingY num
            (muls, ps, s)

Having both will fail. I have no idea why...

@gamebox
Copy link
Collaborator Author

gamebox commented Dec 3, 2024

Note that I've extracted some guard logic out to functions for readability (and because I thought the char literals were causing issues in the guards)

@gamebox
Copy link
Collaborator Author

gamebox commented Dec 4, 2024

This is now fixed on main at the above link. I finally fixed this through some convoluted means of moving all literal matching out into the guards. The issue definitely still exists

@gamebox
Copy link
Collaborator Author

gamebox commented Dec 4, 2024

I'd say the issue comes down to a problem with certain literals appearing in patterns when there are also guards on some of the clauses in a when

@gamebox
Copy link
Collaborator Author

gamebox commented Dec 5, 2024

Now that I'm a collaborator (thanks Richard!), I'm going to take this on.

@gamebox gamebox self-assigned this Dec 5, 2024
@lukewilliamboswell lukewilliamboswell added the bug Something isn't working label Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants