Merge branch 'enfore_not_allowing_big_maps' into 'dev'
Give an error when nesting a big_map inside another big_map See merge request ligolang/ligo!518
This commit is contained in:
commit
91a6affdad
@ -9,8 +9,12 @@ import Syntax from '@theme/Syntax';
|
|||||||
import SyntaxTitle from '@theme/SyntaxTitle';
|
import SyntaxTitle from '@theme/SyntaxTitle';
|
||||||
|
|
||||||
A lazily deserialized map that's intended to store large amounts of data.
|
A lazily deserialized map that's intended to store large amounts of data.
|
||||||
|
Lazily means that storage is read or written per key on demand. Therefore
|
||||||
|
there are no `map`, `fold`, and `iter` operations as in
|
||||||
|
[Map](./map-reference).
|
||||||
|
|
||||||
The gast costs of deserialized maps are higher than standard maps as data is lazily deserialized.
|
The gast costs of big maps are higher than standard maps as data is lazily
|
||||||
|
deserialized.
|
||||||
|
|
||||||
<SyntaxTitle syntax="pascaligo">
|
<SyntaxTitle syntax="pascaligo">
|
||||||
type big_map ('key, 'value)
|
type big_map ('key, 'value)
|
||||||
@ -56,6 +60,8 @@ type register = big_map (address, move);
|
|||||||
|
|
||||||
</Syntax>
|
</Syntax>
|
||||||
|
|
||||||
|
Be aware that a `big_map` cannot appear inside another `big_map`.
|
||||||
|
|
||||||
<SyntaxTitle syntax="pascaligo">
|
<SyntaxTitle syntax="pascaligo">
|
||||||
function empty : big_map ('key, 'value)
|
function empty : big_map ('key, 'value)
|
||||||
</SyntaxTitle>
|
</SyntaxTitle>
|
||||||
|
@ -1338,6 +1338,58 @@ let%expect_test _ =
|
|||||||
ligo: in file "self_bad_entrypoint_format.ligo", line 8, characters 52-58. bad entrypoint format: entrypoint "Toto" is badly formatted. We expect "%bar" for entrypoint Bar and "%default" when no entrypoint used {"location":"in file \"self_bad_entrypoint_format.ligo\", line 8, characters 52-58"}
|
ligo: in file "self_bad_entrypoint_format.ligo", line 8, characters 52-58. bad entrypoint format: entrypoint "Toto" is badly formatted. We expect "%bar" for entrypoint Bar and "%default" when no entrypoint used {"location":"in file \"self_bad_entrypoint_format.ligo\", line 8, characters 52-58"}
|
||||||
|
|
||||||
|
|
||||||
|
If you're not sure how to fix this error, you can
|
||||||
|
do one of the following:
|
||||||
|
|
||||||
|
* Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
|
||||||
|
* Ask a question on our Discord: https://discord.gg/9rhYaEt
|
||||||
|
* Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
|
||||||
|
* Check the changelog by running 'ligo changelog' |}];
|
||||||
|
|
||||||
|
run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_1.religo"; "main"];
|
||||||
|
[%expect {|
|
||||||
|
ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
|
||||||
|
|
||||||
|
|
||||||
|
If you're not sure how to fix this error, you can
|
||||||
|
do one of the following:
|
||||||
|
|
||||||
|
* Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
|
||||||
|
* Ask a question on our Discord: https://discord.gg/9rhYaEt
|
||||||
|
* Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
|
||||||
|
* Check the changelog by running 'ligo changelog' |}];
|
||||||
|
|
||||||
|
run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_2.religo"; "main"];
|
||||||
|
[%expect {|
|
||||||
|
ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
|
||||||
|
|
||||||
|
|
||||||
|
If you're not sure how to fix this error, you can
|
||||||
|
do one of the following:
|
||||||
|
|
||||||
|
* Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
|
||||||
|
* Ask a question on our Discord: https://discord.gg/9rhYaEt
|
||||||
|
* Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
|
||||||
|
* Check the changelog by running 'ligo changelog' |}];
|
||||||
|
|
||||||
|
run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_3.religo"; "main"];
|
||||||
|
[%expect {|
|
||||||
|
ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
|
||||||
|
|
||||||
|
|
||||||
|
If you're not sure how to fix this error, you can
|
||||||
|
do one of the following:
|
||||||
|
|
||||||
|
* Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
|
||||||
|
* Ask a question on our Discord: https://discord.gg/9rhYaEt
|
||||||
|
* Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
|
||||||
|
* Check the changelog by running 'ligo changelog' |}];
|
||||||
|
|
||||||
|
run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_4.religo"; "main"];
|
||||||
|
[%expect {|
|
||||||
|
ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
|
||||||
|
|
||||||
|
|
||||||
If you're not sure how to fix this error, you can
|
If you're not sure how to fix this error, you can
|
||||||
do one of the following:
|
do one of the following:
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ let all_expression_mapper = [
|
|||||||
Literals.peephole_expression ;
|
Literals.peephole_expression ;
|
||||||
]
|
]
|
||||||
let all_type_expression_mapper = [
|
let all_type_expression_mapper = [
|
||||||
Entrypoints_lenght_limit.peephole_type_expression ;
|
Entrypoints_length_limit.peephole_type_expression ;
|
||||||
]
|
]
|
||||||
|
|
||||||
let all_exp = List.map (fun el -> Helpers.Expression el) all_expression_mapper
|
let all_exp = List.map (fun el -> Helpers.Expression el) all_expression_mapper
|
||||||
|
56
src/passes/9-self_ast_typed/no_nested_big_map.ml
Normal file
56
src/passes/9-self_ast_typed/no_nested_big_map.ml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
open Ast_typed
|
||||||
|
open Trace
|
||||||
|
|
||||||
|
type contract_pass_data = Contract_passes.contract_pass_data
|
||||||
|
|
||||||
|
module Errors = struct
|
||||||
|
let no_nested_bigmap () =
|
||||||
|
let title = (thunk ("It looks like you have nested a big map inside another big map. This is not supported. ")) in
|
||||||
|
let message () = "" in
|
||||||
|
let data = [
|
||||||
|
(* ("location" , fun () -> Format.asprintf "%a" Location.pp loc) TODO once types have an actual location *)
|
||||||
|
] in
|
||||||
|
error ~data title message ()
|
||||||
|
end
|
||||||
|
|
||||||
|
let rec check_no_nested_bigmap is_in_bigmap e =
|
||||||
|
match e.type_content with
|
||||||
|
| T_operator (TC_big_map (_, _)) when is_in_bigmap ->
|
||||||
|
fail @@ Errors.no_nested_bigmap
|
||||||
|
| T_operator (TC_big_map (key, value)) ->
|
||||||
|
let%bind _ = check_no_nested_bigmap false key in
|
||||||
|
let%bind _ = check_no_nested_bigmap true value in
|
||||||
|
ok ()
|
||||||
|
| T_operator (TC_contract t)
|
||||||
|
| T_operator (TC_option t)
|
||||||
|
| T_operator (TC_list t)
|
||||||
|
| T_operator (TC_set t) ->
|
||||||
|
let%bind _ = check_no_nested_bigmap is_in_bigmap t in
|
||||||
|
ok ()
|
||||||
|
| T_operator (TC_map (a, b)) ->
|
||||||
|
let%bind _ = check_no_nested_bigmap is_in_bigmap a in
|
||||||
|
let%bind _ = check_no_nested_bigmap is_in_bigmap b in
|
||||||
|
ok ()
|
||||||
|
| T_operator (TC_arrow (a, b)) ->
|
||||||
|
let%bind _ = check_no_nested_bigmap false a in
|
||||||
|
let%bind _ = check_no_nested_bigmap false b in
|
||||||
|
ok ()
|
||||||
|
| T_sum s ->
|
||||||
|
let es = CMap.to_list s in
|
||||||
|
let%bind _ = bind_map_list (fun l -> check_no_nested_bigmap is_in_bigmap l) es in
|
||||||
|
ok ()
|
||||||
|
| T_record elm ->
|
||||||
|
let es = LMap.to_list elm in
|
||||||
|
let%bind _ = bind_map_list (fun l -> check_no_nested_bigmap is_in_bigmap l) es in
|
||||||
|
ok ()
|
||||||
|
| T_arrow { type1; type2 } ->
|
||||||
|
let%bind _ = check_no_nested_bigmap false type1 in
|
||||||
|
let%bind _ = check_no_nested_bigmap false type2 in
|
||||||
|
ok ()
|
||||||
|
| T_variable _
|
||||||
|
| T_constant _ ->
|
||||||
|
ok ()
|
||||||
|
|
||||||
|
let self_typing : contract_pass_data -> expression -> (bool * contract_pass_data * expression) result = fun dat el ->
|
||||||
|
let%bind _ = check_no_nested_bigmap false el.type_expression in
|
||||||
|
ok (true, dat, el)
|
@ -6,6 +6,7 @@ let all_passes = [
|
|||||||
|
|
||||||
let contract_passes = [
|
let contract_passes = [
|
||||||
Contract_passes.self_typing ;
|
Contract_passes.self_typing ;
|
||||||
|
No_nested_big_map.self_typing ;
|
||||||
]
|
]
|
||||||
|
|
||||||
let all_program =
|
let all_program =
|
||||||
|
10
src/test/contracts/negative/nested_bigmap_1.religo
Normal file
10
src/test/contracts/negative/nested_bigmap_1.religo
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
type bar = big_map (nat, int);
|
||||||
|
|
||||||
|
/* this should result in an error as nested big_maps are not supported: */
|
||||||
|
type storage = big_map (int, bar);
|
||||||
|
|
||||||
|
type return = (list (operation), storage);
|
||||||
|
|
||||||
|
let main = ((ignore, store): (unit, storage)): return => {
|
||||||
|
([]: list(operation), store)
|
||||||
|
};
|
9
src/test/contracts/negative/nested_bigmap_2.religo
Normal file
9
src/test/contracts/negative/nested_bigmap_2.religo
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* this should result in an error as nested big_maps are not supported: */
|
||||||
|
type storage = big_map (nat, big_map (int, string));
|
||||||
|
|
||||||
|
type return = (list (operation), storage);
|
||||||
|
|
||||||
|
let main = ((ignore, store): (unit, storage)): return => {
|
||||||
|
([]: list(operation), store)
|
||||||
|
};
|
||||||
|
|
15
src/test/contracts/negative/nested_bigmap_3.religo
Normal file
15
src/test/contracts/negative/nested_bigmap_3.religo
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
type bar = big_map (nat, int);
|
||||||
|
|
||||||
|
type foo = {
|
||||||
|
a: int,
|
||||||
|
b: bar
|
||||||
|
};
|
||||||
|
|
||||||
|
/* this should result in an error as nested big_maps are not supported: */
|
||||||
|
type storage = big_map(nat, foo);
|
||||||
|
|
||||||
|
type return = (list (operation), storage);
|
||||||
|
|
||||||
|
let main = ((ignore, store): (unit, storage)): return => {
|
||||||
|
([]: list(operation), store)
|
||||||
|
};
|
9
src/test/contracts/negative/nested_bigmap_4.religo
Normal file
9
src/test/contracts/negative/nested_bigmap_4.religo
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/* this should result in an error as nested big_maps are not supported: */
|
||||||
|
type storage = map (int, big_map (nat, big_map (int, string)));
|
||||||
|
|
||||||
|
type return = (list (operation), storage);
|
||||||
|
|
||||||
|
let main = ((ignore, store): (unit, storage)): return => {
|
||||||
|
([]: list(operation), store)
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user