diff --git a/src/passes/2-simplify/pascaligo.ml b/src/passes/2-simplify/pascaligo.ml index 31e739f36..8fe81f388 100644 --- a/src/passes/2-simplify/pascaligo.ml +++ b/src/passes/2-simplify/pascaligo.ml @@ -792,7 +792,8 @@ and simpl_single_instruction : Raw.single_instr -> (_ -> expression result) resu let (a , loc) = r_split a in let%bind value_expr = match a.rhs with | Expr e -> simpl_expression e - | NoneExpr reg -> fail @@ unsupported_ass_None reg + (* | NoneExpr reg -> fail @@ unsupported_ass_None reg *) + | NoneExpr reg -> simpl_expression (Raw.EConstr (Raw.NoneExpr reg)) in match a.lhs with | Path path -> ( diff --git a/src/passes/4-typer/typer.ml b/src/passes/4-typer/typer.ml index 391239506..7eba933bf 100644 --- a/src/passes/4-typer/typer.ml +++ b/src/passes/4-typer/typer.ml @@ -615,6 +615,8 @@ and type_expression : environment -> ?tv_opt:O.type_value -> I.expression -> O.a let output_type = body.type_annotation in return (E_lambda {binder = fst binder ; body}) (t_function input_type output_type ()) ) + | E_constant ("NONE", []) -> + return (E_constant ("NONE", [])) (t_option_none ()) | E_constant (name, lst) -> let%bind lst' = bind_list @@ List.map (type_expression e) lst in let tv_lst = List.map get_type_annotation lst' in diff --git a/src/passes/6-transpiler/transpiler.ml b/src/passes/6-transpiler/transpiler.ml index 0cef7b26b..acc4bd7e1 100644 --- a/src/passes/6-transpiler/transpiler.ml +++ b/src/passes/6-transpiler/transpiler.ml @@ -130,6 +130,8 @@ let rec transpile_type (t:AST.type_value) : type_value result = | T_constant ("option", [o]) -> let%bind o' = transpile_type o in ok (T_option o') + | T_constant ("option_none", []) -> + ok (T_option (T_base Base_unit)) | T_constant (name , _lst) -> fail @@ unrecognized_type_constant name (* TODO hmm *) | T_sum m -> diff --git a/src/passes/6-transpiler/untranspiler.ml b/src/passes/6-transpiler/untranspiler.ml index 78c41cca8..08ed0d141 100644 --- a/src/passes/6-transpiler/untranspiler.ml +++ b/src/passes/6-transpiler/untranspiler.ml @@ -107,12 +107,14 @@ let rec untranspile (v : value) (t : AST.type_value) : AST.annotated_expression get_string v in return (E_literal (Literal_address n)) ) + | T_constant ("option_none", []) -> + ok e_a_empty_none | T_constant ("option", [o]) -> ( let%bind opt = trace_strong (wrong_mini_c_value "option" v) @@ get_option v in match opt with - | None -> ok (e_a_empty_none o) + | None -> ok e_a_empty_none | Some s -> let%bind s' = untranspile s o in ok (e_a_empty_some s') diff --git a/src/stages/ast_typed/combinators.ml b/src/stages/ast_typed/combinators.ml index d9dcebb73..5ae376b9d 100644 --- a/src/stages/ast_typed/combinators.ml +++ b/src/stages/ast_typed/combinators.ml @@ -25,6 +25,7 @@ let t_tez ?s () : type_value = make_t (T_constant ("tez", [])) s let t_timestamp ?s () : type_value = make_t (T_constant ("timestamp", [])) s let t_unit ?s () : type_value = make_t (T_constant ("unit", [])) s let t_option o ?s () : type_value = make_t (T_constant ("option", [o])) s +let t_option_none ?s () : type_value = make_t (T_constant ("option_none", [])) s let t_tuple lst ?s () : type_value = make_t (T_tuple lst) s let t_list t ?s () : type_value = make_t (T_constant ("list", [t])) s let t_set t ?s () : type_value = make_t (T_constant ("set", [t])) s @@ -254,7 +255,7 @@ let e_a_address s = make_a_e (e_address s) (t_address ()) let e_a_pair a b = make_a_e (e_pair a b) (t_pair a.type_annotation b.type_annotation ()) let e_a_some s = make_a_e (e_some s) (t_option s.type_annotation ()) let e_a_lambda l in_ty out_ty = make_a_e (e_lambda l) (t_function in_ty out_ty ()) -let e_a_none t = make_a_e e_none (t_option t ()) +let e_a_none = make_a_e e_none (t_option_none ()) let e_a_tuple lst = make_a_e (E_tuple lst) (t_tuple (List.map get_type_annotation lst) ()) let e_a_record r = make_a_e (e_record r) (t_record (SMap.map get_type_annotation r) ()) let e_a_application a b = make_a_e (e_application a b) (get_type_annotation b) diff --git a/src/stages/ast_typed/combinators_environment.ml b/src/stages/ast_typed/combinators_environment.ml index 1446c8780..3cea2fd1d 100644 --- a/src/stages/ast_typed/combinators_environment.ml +++ b/src/stages/ast_typed/combinators_environment.ml @@ -12,7 +12,7 @@ let e_a_empty_string s = e_a_string s Environment.full_empty let e_a_empty_address s = e_a_address s Environment.full_empty let e_a_empty_pair a b = e_a_pair a b Environment.full_empty let e_a_empty_some s = e_a_some s Environment.full_empty -let e_a_empty_none t = e_a_none t Environment.full_empty +let e_a_empty_none = e_a_none Environment.full_empty let e_a_empty_tuple lst = e_a_tuple lst Environment.full_empty let e_a_empty_record r = e_a_record r Environment.full_empty let e_a_empty_map lst k v = e_a_map lst k v Environment.full_empty diff --git a/src/stages/ast_typed/misc.ml b/src/stages/ast_typed/misc.ml index 5ba66b4ea..b7fb63f76 100644 --- a/src/stages/ast_typed/misc.ml +++ b/src/stages/ast_typed/misc.ml @@ -296,6 +296,9 @@ let rec assert_type_value_eq (a, b: (type_value * type_value)) : unit result = m bind_list_iter assert_type_value_eq (List.combine ta tb) ) | T_tuple _, _ -> fail @@ different_kinds a b + | T_constant ("option", _), T_constant ("option_none", []) | + T_constant ("option_none", []), T_constant ("option", _) -> + ok () | T_constant (ca, lsta), T_constant (cb, lstb) -> ( let%bind _ = trace_strong (different_size_constants a b) diff --git a/src/test/contracts/option.ligo b/src/test/contracts/option.ligo index c2d36439d..9abf2c845 100644 --- a/src/test/contracts/option.ligo +++ b/src/test/contracts/option.ligo @@ -4,3 +4,12 @@ type foobar is option(int) const s : foobar = Some(42) const n : foobar = None + +function assign (var m : int) : foobar is + var coco : foobar := None; + block +{ + coco := Some(m); + coco := None; +} +with coco diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 16a4c7d69..b558d08dd 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -368,6 +368,10 @@ let option () : unit result = let expected = e_typed_none t_int in expect_eq_evaluate program "n" expected in + let%bind () = + let expected = e_typed_none t_int in + expect_eq program "assign" (e_int 12) expected + in ok () let moption () : unit result =