Incorrect Michelson code generated from LIGO
Compiling this (seemingly type-correct) CameLIGO code results on an incorrect Michelson code:
let rec ref_join
(params: int * (int -> int -> int))
: int * int =
let left = 1 in
ref_join
( 1
, (fun (mem: int) (new_: int) ->
if left > 0 then 0 else left+1)
)
let main (ign: unit * unit): operation list * unit =
let ign = ref_join (1, (fun (m: int) (r: int) -> 0)) in
([] : operation list), ()
(I extracted this snippet from a longer code, hence it doesn't make any sense as-is).
Output:
Error(s) occurred while type checking the contract:
Ill typed contract:
01: { parameter unit ;
02: storage unit ;
03: code { DROP
04: /* [] */ ;
05: LAMBDA
06: int
07: (lambda int int)
08: { /* [ @arg int ] */
09: DROP
10: /* [] */ ;
11: LAMBDA
12: int
13: int
14: { /* [ @arg int ] */ DROP /* [] */ ; PUSH int 0 /* [ int ] */ }
15: /* [ lambda int int ] */ }
16: /* [ lambda int (lambda int int) ] */ ;
17: PUSH int 1
18: /* [ int : lambda int (lambda int int) ] */ ;
19: PAIR
20: /* [ pair int (lambda int (lambda int int)) ] */ ;
21: LEFT (pair int int)
22: /* [ or (pair int (lambda int (lambda int int))) (pair int int) ] */ ;
23: LOOP_LEFT
24: { DROP
25: /* [] */ ;
26: PUSH int 1
27: /* [ int ] */ ;
28: LAMBDA
29: (pair (pair int int) int)
30: (lambda int int)
31: { CAR
32: /* [ pair int int ] */ ;
33: LAMBDA
34: (pair (pair int int) int)
35: int
36: { CAR
37: /* [ pair int int ] */ ;
38: PUSH int 0
39: /* [ int : pair int int ] */ ;
40: SWAP
41: /* [ pair int int : int ] */ ;
42: DUP
43: /* [ pair int int : pair int int : int ] */ ;
44: DUG 2
45: /* [ pair int int : int : pair int int ] */ ;
46: COMPARE ;
47: GT ;
48: IF { DROP ; PUSH int 0 } { PUSH int 1 ; ADD } } ;
49: SWAP ;
50: APPLY } ;
51: SWAP ;
52: APPLY ;
53: PUSH int 1 ;
54: PAIR ;
55: LEFT (pair int int) } ;
56: DROP ;
57: PUSH unit Unit ;
58: NIL operation ;
59: PAIR } }
At line 46 characters 21 to 28, wrong stack type for instruction COMPARE:
[ pair int int : int : ... ].
Bad stack item 1.
Type pair int int is not compatible with type int.
My uninformed guess is that something is going wrong when capturing a value from outer scope inside the lambda. However, I couldn't pinpoint the exact reason, since on this example seemingly irrelevant changes can also make the error disappear. Also, the issue is not with COMPARE
instruction, pretty much anything you do inside the callback using left
from outer scope won't type check.
If this is indeed an error, I would appreciate if someone can point out to me the exact reason, so I can try to find a workaround on my code.
I can reproduce the issue both with LIGO 5.0 and the current tip of the dev
branch (7bbd81f8).