Compiler crash with number literal in guard
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
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`,
),
),
]
The44 number literal in the pattern looks like the desugared version of the ',' char literal in that match clause
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...
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)
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
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
Now that I'm a collaborator (thanks Richard!), I'm going to take this on.